使用 LocalStack 和 Docker 开发及测试 AWS 云应用程序
在现代应用开发中,将云应用程序部署到生产环境之前先在本地进行测试,有助于更快、更自信地发布。这种方法涉及在本地模拟服务,尽早识别和修复问题,并快速迭代,而无需承担成本或面对完整云环境的复杂性。像 LocalStack 这样的工具在此过程中变得非常宝贵,使您能够模拟 AWS 服务并容器化应用程序,以实现一致的、隔离的测试环境。
在本指南中,您将学习如何
- 使用 Docker 启动 LocalStack 容器
- 从非容器化应用程序连接到 LocalStack
- 从容器化应用程序连接到 LocalStack
什么是 LocalStack?
LocalStack 是一个云服务模拟器,它可以在您的笔记本电脑上的单个容器中运行。它提供了一种功能强大、灵活且经济高效的方法,用于在本地测试和开发基于 AWS 的应用程序。
为什么使用 LocalStack?
在本地模拟 AWS 服务,您可以测试应用程序如何与 S3、Lambda 和 DynamoDB 等服务交互,而无需连接真实的 AWS 云。您可以快速迭代开发,避免在此阶段部署到云端的成本和复杂性。
通过在本地模拟这些服务的行为,LocalStack 可以实现更快的反馈循环。您的应用程序可以与外部 API 交互,但所有内容都在本地运行,无需处理云资源调配或网络延迟。
这使得验证集成和测试基于云的场景变得更容易,而无需在生产环境中配置 IAM 角色或策略。您可以在本地模拟复杂的云架构,只有在准备好时才将更改推送到 AWS。
将 LocalStack 与 Docker 结合使用
LocalStack 的 官方 Docker 镜像 提供了一种便捷的方式,可在您的开发机器上运行 LocalStack。它是免费使用的,运行无需任何 API 密钥。您甚至可以使用 LocalStack Docker Extension,通过图形用户界面使用 LocalStack。
先决条件
本操作指南需要以下先决条件
- Docker Desktop
- Node.js
- Python 和 pip
- Docker 基础知识
启动 LocalStack
使用以下步骤快速启动 LocalStack 演示
首先 克隆示例应用程序。打开终端并运行以下命令
$ git clone https://github.com/dockersamples/todo-list-localstack-docker $ cd todo-list-localstack-docker
启动 LocalStack
运行以下命令启动 LocalStack。
$ docker compose -f compose-native.yml up -d
此 Compose 文件还包含所需的 Mongo 数据库规范。您可以通过访问 Docker Desktop Dashboard 来验证服务是否已启动并正在运行。
通过选择容器并检查日志来验证 LocalStack 是否已启动并正在运行。
创建本地 Amazon S3 存储桶
当您使用 LocalStack 创建本地 S3 存储桶时,实际上是在模拟在 AWS 上创建 S3 存储桶。这使您无需实际的 AWS 账户即可测试和开发与 S3 交互的应用程序。
要创建本地 Amazon S3 存储桶,您需要在系统上安装
awscli-local
软件包。此软件包提供awslocal
命令,它是 AWS 命令行接口的一个精简包装器,用于 LocalStack。它让您可以在本地机器上的模拟环境中进行测试和开发,而无需访问真实的 AWS 服务。您可以在此处了解更多关于此实用工具的信息。$ pip install awscli-local
使用以下命令在 LocalStack 环境中创建一个新的 S3 存储桶
$ awslocal s3 mb s3://mysamplebucket
命令
s3 mb s3://mysamplebucket
告诉 AWS CLI 创建一个名为mysamplebucket
的新 S3 存储桶(mb 代表make bucket
,创建存储桶)。您可以通过在 Docker Desktop Dashboard 上选择 LocalStack 容器并查看日志来验证 S3 存储桶是否已创建。日志表明您的 LocalStack 环境已正确配置,您现在可以使用
mysamplebucket
来存储和检索对象。
在开发中使用 LocalStack
现在您已经熟悉了 LocalStack,是时候看看它的实际应用了。在此演示中,您将使用一个包含 React 前端和 Node.js 后端的示例应用程序。此应用程序栈使用以下组件:
- React:用户友好的前端,用于访问待办事项列表应用程序
- Node:负责处理 HTTP 请求的后端。
- MongoDB:一个用于存储所有待办事项列表数据的数据库
- LocalStack:模拟 Amazon S3 服务并存储和检索图像。


从非容器化应用连接到 LocalStack
现在是时候将您的应用程序连接到 LocalStack 了。index.js
文件位于 backend/
目录中,是后端应用程序的主要入口点。
代码与 LocalStack 的 S3 服务交互,该服务通过 S3_ENDPOINT_URL
环境变量定义的端点进行访问,该端点通常在本地开发中设置为 http://localhost:4556
。
AWS SDK 中的 S3Client
配置为使用此 LocalStack 端点,以及同样来自环境变量的测试凭证(AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
)。此设置允许应用程序在本地模拟的 S3 服务上执行操作,如同与真实的 AWS S3 交互一样,这使得代码在不同环境中具有灵活性。
代码使用 multer
和 multer-s3
来处理文件上传。当用户通过 /upload 路由上传图像时,文件直接存储在 LocalStack 模拟的 S3 存储桶中。存储桶名称从环境变量 S3_BUCKET_NAME
中检索。每个上传的文件通过在原始文件名后附加当前时间戳来获得唯一名称。然后,该路由返回本地 S3 服务中上传文件的 URL,使其可以像托管在真实的 AWS S3 存储桶中一样访问。
让我们看看实际操作。首先启动 Node.js 后端服务。
切换到
backend/
目录$ cd backend/
安装所需的依赖项
$ npm install
设置 AWS 环境变量
位于
backend/
目录中的.env
文件已经包含 LocalStack 用于模拟 AWS 服务的占位符凭证和配置值。AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
是占位符凭证,而S3_BUCKET_NAME
和S3_ENDPOINT_URL
是配置设置。由于这些值已针对 LocalStack 正确设置,因此无需进行任何更改。提示
考虑到您在 Docker 容器中运行 Mongo,并且后端 Node 应用程序在您的主机上原生运行,请确保在您的
.env
文件中设置了MONGODB_URI=mongodb://localhost:27017/todos
。MONGODB_URI=mongodb://localhost:27017/todos AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test S3_BUCKET_NAME=mysamplebucket S3_ENDPOINT_URL=http://localhost:4566 AWS_REGION=us-east-1
尽管 AWS SDK 通常可能使用以
AWS_
开头的环境变量,但此特定应用程序直接引用index.js
文件(位于backend/
目录下)中的以下S3_*
变量来配置S3Client
。const s3 = new S3Client({ endpoint: process.env.S3_ENDPOINT_URL, // Use the provided endpoint or fallback to defaults credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'default_access_key', // Default values for development secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'default_secret_key', }, });
启动后端服务器
$ node index.js
您将看到后端服务已在端口 5000 成功启动的消息。
启动前端服务
要启动前端服务,请打开新的终端并按照以下步骤操作
导航到
frontend
目录$ cd frontend
安装所需的依赖项
$ npm install
启动前端服务
$ npm run dev
现在,您应该看到以下消息
VITE v5.4.2 ready in 110 ms ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ press h + enter to show help
您现在可以通过 http://localhost:5173 访问该应用程序。请选择一个图像文件并点击“Upload”(上传)按钮来上传图像。
您可以通过检查 LocalStack 容器日志来验证图像是否已上传到 S3 存储桶
状态码
200
表示putObject
操作(涉及将对象上传到 S3 存储桶)在 LocalStack 环境中成功执行。LocalStack 记录此条目,以便了解正在执行的操作。这有助于调试和确认您的应用程序是否正在正确地与模拟的 AWS 服务交互。由于 LocalStack 旨在在本地模拟 AWS 服务,此日志条目表明您的应用程序在本地沙箱环境中执行云操作时按预期工作。
从容器化 Node 应用连接到 LocalStack
既然您已经学会了如何将非容器化的 Node.js 应用程序连接到 LocalStack,现在是时候探索在容器化环境中运行完整应用程序栈所需的更改了。为此,您将创建一个 Compose 文件,指定所有必需的服务 - 前端、后端、数据库和 LocalStack。
检查 Docker Compose 文件。
以下 Docker Compose 文件定义了四个服务:
backend
、frontend
、mongodb
和localstack
。backend
和frontend
服务是您的 Node.js 应用程序,而mongodb
提供数据库,localstack
模拟像 S3 这样的 AWS 服务。backend
服务依赖于localstack
和mongodb
服务,确保它们在启动前运行。它还使用.env
文件来设置环境变量。frontend
服务依赖于backend
并设置 API URL。mongodb
服务使用持久卷进行数据存储,而localstack
配置为运行 S3 服务。此设置使您能够在本地使用类似 AWS 的服务开发和测试应用程序。services: backend: build: context: ./backend dockerfile: Dockerfile ports: - 5000:5000 depends_on: - localstack - mongodb env_file: - backend/.env frontend: build: context: ./frontend dockerfile: Dockerfile ports: - 5173:5173 depends_on: - backend environment: - REACT_APP_API_URL=http://backend:5000/api mongodb: image: mongo container_name: mongodb volumes: - mongodbdata:/data/db ports: - 27017:27017 localstack: image: localstack/localstack container_name: localstack ports: - 4566:4566 environment: - SERVICES=s3 - GATEWAY_LISTEN=0.0.0.0:4566 volumes: - ./localstack:/docker-entrypoint-initaws.d" volumes: mongodbdata:
修改
backend/
目录下的.env
文件,使资源使用内部网络名称进行连接。提示
根据之前的 Compose 文件,应用程序将使用主机名
localstack
连接到 LocalStack,而 Mongo 将使用主机名mongodb
连接。MONGODB_URI=mongodb://mongodb:27017/todos AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test S3_BUCKET_NAME=mysamplebucket S3_ENDPOINT_URL=http://localstack:4566 AWS_REGION=us-east-1
停止正在运行的服务
通过在终端中按“Ctrl+C”确保停止上一步中的 Node 前端和后端服务。此外,您需要通过在 Docker Desktop Dashboard 中选择 LocalStack 和 Mongo 容器并点击“Delete”(删除)按钮来停止它们。
在您克隆的项目目录的根目录下执行以下命令来启动应用程序栈
$ docker compose -f compose.yml up -d --build
稍等片刻,应用程序将启动并运行。
手动创建一个 S3 存储桶
AWS S3 存储桶不会由 Compose 文件预先创建。运行以下命令在 LocalStack 环境中创建一个新的存储桶
$ awslocal s3 mb s3://mysamplebucket
该命令创建一个名为
mysamplebucket
的 S3 存储桶。打开 http://localhost:5173 访问完整的待办事项列表应用程序,并开始向 Amazon S3 存储桶上传图像。
提示
为了优化性能并减少开发过程中的上传时间,请考虑上传较小的图像文件。较大的图像可能需要更长时间处理,并可能影响应用程序的整体响应速度。
总结
本指南已向您介绍了如何使用 LocalStack 和 Docker 设置本地开发环境。您已学会如何在本地测试基于 AWS 的应用程序,从而降低成本并提高开发工作流程的效率。