问题描述
我正在使用 docker-compose 在 2 个单独的容器中运行一个 python API 和一个 Localstack 实例,用于本地开发。
API 有一个端点,它生成一个预先签名的 AWS S3 URL 并重定向用户,以便直接从 S3 加载图像。
在本地开发中,API 使用 localstack 容器的地址作为自定义端点 url(即:boto3.client("s3",endpoint_url="http://localstack:4566")
)实例化 boto3 客户端,允许 API 访问 localstack 容器内的资源。
问题是 boto3 客户端返回的预签名 URL 使用了 localstack
地址,浏览器无法加载它,因为 localstack 资源暴露给主机,位于 http://localhost:4566
。
如果我尝试在 boto3 客户端实例化中将 aws 资源端点 url 设置为 localhost
,则在容器内运行的 API 将在其中查找 AWS 资源 OWN CONTAINER 的本地主机,而不是主机,本地堆栈资源在其中公开。
有什么方法可以使用相同的地址从主机的浏览器和不同的容器访问在 docker 容器中运行的 localstack 资源吗?
[Edit] 我在 mac 上使用 docker,以防发生任何改变 [/Edit]
解决方法
也许您可以尝试一下 host.docker.internal:4566
,因为很可能只有 localstack 服务会监听它。
我不确定,但我不知道在您的本地 API 调用中为什么将您的端点称为 endpoint_url="http://localstack:4566"
重点是您的 localstack 在端点 localhost
上运行并公开端口 4566
http://localhost:4566
所以你的本地客户端连接应该是这样的:
boto3.client('s3',endpoint_url='http://localhost:4566')
然后您的本地客户端将能够连接到 localstack s3 服务。
如果您有问题,分享您的 docker-compose 可能会有所帮助,但就我而言,我使用 localhost:4566
更新:
选项 1:
要在同一个容器中运行或创建任何资源,我更愿意使用 docker-entrypoint-initaws.d
=> 创建一个脚本,该脚本将执行任何 CLI 命令以创建端点为 loclahost:4566
的资源,然后附加到您的 docker-compose 卷标签。
另一个选项是这样的:
选项 2:
local-stack:
.........
.........
networks:
- my_awesome_network
setup-resources:
image: mesosphere/aws-cli
environment:
AWS_ACCESS_KEY_ID: SOMESECRETACCESS
AWS_SECRET_ACCESS_KEY: SOMESECRETKEY
AWS_DEFAULT_REGION: eu-west-1
entrypoint: /bin/sh -c
command: >
"
# SIMPLE WRITE AN WHILE LOOP USING CURL COMMAND FOR http://localstack:4566
sleep 10;
aws sqs create-queue --endpoint-url=http://localstack:4566 --queue-name my_queue;
"
networks:
- my_awesome_network
depends_on:
- local-stack