自动在本地堆栈上创建S3存储桶

75

在我的docker-compose中使用localstack主要模拟S3。

我知道我可以创建存储桶,这不是问题。我想做的是在运行docker-compose up时自动创建存储桶。

localstack中是否已经内置了此功能?

5个回答

93

自版本0.10.0起,引入了这个提交所带来的变化。

当容器第一次启动时,它将执行位于/docker-entrypoint-initaws.d目录下扩展名为.sh的文件。文件将按字母顺序执行。您可以在初始化脚本中使用awslocal (或aws) cli工具轻松创建本地堆栈上的aws资源。

在v1.1.0之前

version: '3.7'
services:
  localstack:
    image: localstack/localstack
    environment:
      - SERVICES=s3
    ports:
      - "4566:4566"
      # - "4572:4572" Old S3 port
    volumes:
      - ./aws:/docker-entrypoint-initaws.d
v1.1.0版本之后

/docker-entrypoint-initaws.d目录的使用已被弃用。在/etc/localstack/init/.d中,可插拔式初始化钩子(Pluggable initialization hooks)已替代旧版的Init scripts。前者将在2.0版本中完全移除。


参考:localstack/localstack/issues/7257

初始化钩子请参阅官方文档

version: '3.7'
services:
  localstack:
    image: localstack/localstack
    environment:
      - SERVICES=s3
    ports:
      - "4566:4566"
    volumes:
      - ./aws:/etc/localstack/init/ready.d

有一个位于目录 ./aws/buckets.sh 中的脚本:

#!/usr/bin/env bash
awslocal s3 mb s3://bucket

会产生以下输出:

v1.1.0之前

...
localstack_1  | Starting mock S3 (http port 4572)...
localstack_1  | Waiting for all LocalStack services to be ready
localstack_1  | Ready.
localstack_1  | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initaws.d/buckets.sh
localstack_1  | make_bucket: bucket
localstack_1  |

在版本 v1.1.0 之后

localstack-1  | Ready.
localstack-1  | 2023-01-05T18:07:50.163  INFO --- [-functhread8] l.services.motoserver      : starting moto server on http://0.0.0.0:40443
localstack-1  | 2023-01-05T18:07:50.165  INFO --- [   asgi_gw_0] localstack.services.infra  : Starting mock S3 service on http port 4566 ...
localstack-1  | 2023-01-05T18:07:50.324  INFO --- [   asgi_gw_0] localstack.request.aws     : AWS s3.CreateBucket => 200
localstack-1  | make_bucket: bucket

1
答案中的脚本部分略有错误。mbs3的顺序颠倒了!应该是awslocal s3 mb s3://bucket。不过还是感谢您的回答,帮我省去了很多麻烦! - Matt Keen
1
@MattKeen,请问 docker-entrypoint-initaws.d 目录及其内容(.sh 脚本)应该在 localstack 容器中创建在哪里?我已经尝试将其创建在 /usr/local/bin//opt/code/localstack/ 中,但似乎在容器启动时 .sh 脚本并没有被执行。 - feature_not_bug
1
根据上述配置,它们应该在/docker-entrypoint-initaws.d中,因此./aws/buckets.sh将变为/docker-entrypoint-initaws.d/buckets.sh - Matthew Warman
太好了,谢谢。你有什么想法可以让我的健康检查等待这个存储桶被创建吗? - Boris Le Méec
这可能作为健康检查的测试有效:test: "awslocal s3api head-bucket --bucket bucket" - Matthew Warman
显示剩余2条评论

8

我能够通过使用Localstack实现这一点,采用了一种“变通”的方法:

  1. Start Localstack

  2. Create expected buckets, e.g.:

    aws --endpoint-url=http://localhost:4572 s3 mb s3://test1   
    
  3. Above line will update the s3_api_calls.json file in the Localstack directory (by default on Linux it's /tmp/localstack/data

  4. Backup the file

  5. Put the copied file in the Localstack directory ( /tmp/localstack/data by default) before starting the stack again

  6. You should be able to see something like 2019-03-21T08:38:28:INFO:localstack.utils.persistence: Restored 2 API calls from persistent file: /tmp/localstack/data/s3_api_calls.json the in startup log after you start Localstack again and the bucket should be available: aws --endpoint-url=http://localhost:4572 s3 ls s3://test1


6

重要提示:LocalStack v1.1.3及以上版本的用户注意

自2022年12月1日起,LocalStack在发布v1.3.0版本时,宣布弃用旧版init脚本(/docker-entrypoint-initaws.d)。新版可插拔初始化钩子是在v1.1.0中引入的。

在v2.0.0中将会完全移除旧版init脚本,这对于使用最新版本LocalStack的任何人都存在风险。

这将是一个破坏性变更。

为了未来的兼容性,原接受的答案仍然有效,但我建议将/docker-entrypoint-initaws.d替换为/etc/localstack/init/ready.d

这将模仿先前的预期行为,因为它将挂钩到LocalStack实际创建您的S3存储桶的READY阶段,同时确保您仍然可以继续更新LocalStack。

这将是当前最佳的Dockerfile

version: '3.8'
services:
  localstack:
    image: localstack/localstack:latest
    environment:
      - SERVICES=s3
    ports:
      - "4566:4566"
    volumes:
      - ./aws:/etc/localstack/init/ready.d

0
只需花一天时间把它做对。我们开始吧!
目标是:使用localstack运行docker-compose,创建S3存储桶s3://this-is-my-bucket,并从项目源中复制一些JSON文件。
LOCALSTACK_BUILD_VERSION: 最新版本为2.1.1.dev
Docker compose:
localstack:
  image: localstack/localstack:latest
  networks:
    - hmpps
  container_name: localstack
  ports:
    - "4566-4597:4566-4597"
    - 8999:8080
    - 9080:9080
  environment:
    - SERVICES=s3
    - PORT_WEB_UI=9080
    - DEBUG=${DEBUG- }
    - DATA_DIR=/tmp/localstack/data
    - DOCKER_HOST=unix:///var/run/docker.sock
    - DEFAULT_REGION=eu-west-2
  volumes:
    - "./src/test/resources/test-data:/tmp/localstack/test-data"
    - "$PWD/src/test/resources/localstack/setup-s3.sh:/etc/localstack/init/ready.d/init-aws.sh"
    - "/var/run/docker.sock:/var/run/docker.sock"

两个重要的事情在这里:
1. src/test/resources/test-data - 是您的json文件的源文件夹 2. src/test/resources/localstack/setup-s3.sh - 是在docker-compose期间运行的脚本文件

enter image description here

脚本文件 setup-s3.sh

#!/usr/bin/env bash
set -e
export TERM=ansi
export AWS_ACCESS_KEY_ID=foobar
export AWS_SECRET_ACCESS_KEY=foobar
export AWS_DEFAULT_REGION=eu-west-2
export PAGER=

echo "S3 Configuration started"

aws --endpoint-url=http://localhost:4566 s3 mb s3://this-is-my-bucket
aws --endpoint-url=http://localhost:4566 s3 cp /tmp/localstack/test-data/ s3://this-is-my-bucket/chart --recursive

echo "S3 Configured"

看看 "aws cp" 命令的 "--recursive" 参数。 这花了我们4个小时!
没有 "--recursive" 就不起作用。太疯狂了! logstack docker logs:
2023-06-22 17:07:00 S3 Configuration started
2023-06-22 17:07:01 2023-06-22T16:07:01.070  INFO --- [   asgi_gw_0] localstack.request.aws     : AWS s3.CreateBucket => 200
2023-06-22 17:07:01 make_bucket: this-is-my-bucket
2023-06-22 17:07:01 2023-06-22T16:07:01.431  INFO --- [   asgi_gw_0] localstack.request.aws     : AWS s3.PutObject => 200
upload: ../../../tmp/localstack/test-data/1a.json to s3://this-is-my-bucket/chart/1a.json
2023-06-22 17:07:01 S3 Configured

本地堆栈S3存储桶的用户界面已经到位 http://s3.localhost.localstack.cloud:4566/this-is-my-bucket 在此输入图像描述

不确定是否需要,我们有application-test.yml属性文件

aws:
  region-name: eu-west-2
  endpoint-url: "http://localhost:4566"
  access_key: foobar
  secret_access_key: foobar
  s3:
    access_key: foobar
    secret_access_key: foobar
    bucket_name: this-is-my-bucket

下一个目标是编写一个集成测试,指向localstack s3://this-is-my-bucket bucket,加载"chart/1a.json"文件,并运行断言魔法。
谢谢!

-2

DATA_DIR: 本地目录,用于保存持久化数据(目前仅支持以下服务:Kinesis、DynamoDB、Elasticsearch、S3)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接