各组件在哪里运行
| AWS 服务 | 本地替代方案 | 本地工作流 |
|---|---|---|
| ECS 任务、Fargate 任务 | Docker Compose 搭配任务镜像 | 配合健康检查和已发布端口,一起运行各服务 |
| Lambda(容器镜像) | 包含 Runtime Interface Emulator 的 Lambda 基础镜像 | 在原生 arm64 上通过 HTTP 调用函数 |
| S3 及其他 AWS API | LocalStack | 在本地开发 S3 存储桶与对象操作 |
| EKS | kubectl 和 k9s 连接真实集群;kwok 提供本地 API | 本地构建和测试,再用 kubectl 和 k9s 操作集群 |
将 ECS 和 Fargate 任务作为 Compose 项目运行
ECS 任务定义是一组容器,包含镜像、环境、端口映射、健康检查和启动顺序。Compose 描述的也是这些内容,因此可以直接转换:每个容器定义对应一个服务。
| 任务定义 | compose.yaml |
|---|---|
image | image |
environment, secrets | environment、env_file(不要将真实机密放入文件) |
portMappings | ports |
healthCheck | healthcheck |
dependsOn 搭配 HEALTHY | depends_on 搭配 condition: service_healthy |
runtimePlatform.cpuArchitecture | platform: linux/amd64 或 linux/arm64 |
services:
api:
image: ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/api:1.4.0
platform: linux/amd64 # match the task's cpuArchitecture
environment:
DATABASE_URL: postgres://postgres:dev@db:5432/app
ports: ["8080:8080"]
depends_on:
db:
condition: service_healthy
db:
image: postgres:17-alpine
environment:
POSTGRES_PASSWORD: dev
POSTGRES_DB: app
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 2s
retries: 30 docker compose up -d --wait # returns when db is healthy and api has started
curl localhost:8080/health
docker compose down -v 我们在 Oxcart 上使用 Postgres 17 和受 service_healthy 条件约束的 nginx 服务验证了此模式:up --wait 返回时,两者均健康,已发布端口可通过 localhost 响应。对于在 Mac 上构建的 amd64 镜像,运行时也需传入相同平台;本地构建的 amd64 专用镜像只有设置 --platform linux/amd64(或 Compose 中的 platform:)才能找到。
在本地运行并调用 Lambda 容器镜像
- 编写处理函数。 创建
app.py,定义返回字典的handler(event, context)函数,例如{"statusCode": 200, "body": "hello"}。 - 编写 Dockerfile。 以包含 Runtime Interface Emulator 的 AWS Lambda 基础镜像开始:
FROM public.ecr.aws/lambda/python:3.13,然后添加COPY app.py ${LAMBDA_TASK_ROOT}/和CMD ["app.handler"]。 - 构建镜像。 运行
docker build -t my-lambda .。如果函数配置为 x86_64,请添加--platform linux/amd64。 - 运行。 运行
docker run -d -p 9000:8080 my-lambda。模拟器在容器内监听端口 8080。 - 调用。 运行
curl -XPOST localhost:9000/2015-03-31/functions/function/invocations -d '{}'。响应就是处理函数的返回值,docker logs会显示带耗时的 Lambda REPORT 行。
测试中,函数返回 {"statusCode": 200, "body": "hello from lambda on aarch64"},容器日志显示 Lambda REPORT 行,耗时 19 ms。模拟器由 AWS 提供,是“Lambda Runtime 和 Extensions API 的代理”,提供 /2015-03-31/functions/function/invocations 端点。
通过 LocalStack 使用 AWS API
LocalStack 在端口 4566 的单个容器中模拟 AWS API。我们在 Oxcart 上运行了 4.9 镜像,并对 S3 进行端到端验证:
docker run -d --name localstack -p 4566:4566 localstack/localstack:4.9
curl -s localhost:4566/_localstack/health # s3, lambda, dynamodb… "available"
curl -X PUT localhost:4566/my-bucket # create a bucket
curl -X PUT --data-binary hello localhost:4566/my-bucket/hello.txt
curl localhost:4566/my-bucket/hello.txt # hello 基于它开发前,先了解许可证条件。自 2026 年 3 月 23 日起,最新 LocalStack 版本需要 LocalStack 账户和身份验证令牌;若未设置 LOCALSTACK_AUTH_TOKEN,最新镜像会报“License activation failed”并退出。LocalStack 免费 Hobby 套餐仅供非商业使用,ECS 从 Base 套餐起提供,EKS 从 Ultimate 套餐起提供。
推送到 ECR 并部署
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin ACCOUNT.dkr.ecr.us-east-1.amazonaws.com
docker buildx build --platform linux/amd64 --load -t ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/api:1.4.0 .
docker push ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/api:1.4.0 Oxcart 将仓库密码保存在 macOS 钥匙串中,而非 ~/.docker/config.json。Oxcart 不支持推送多平台镜像:请为每种架构推送一个标签,或通过 CI 发布多架构清单。
从 Mac 使用 EKS
aws eks update-kubeconfig --name my-cluster 将集群添加到 kubeconfig,让你能从 macOS 使用 kubectl 和 k9s。用 Oxcart 在本地开发并测试服务,再将同一镜像部署到 EKS。对于本地清单和控制器测试,kwok 提供真实的 Kubernetes API 服务器和模拟节点。Mac 上的 Kubernetes 指南介绍了如何配合使用这些工作流。
本地迭代为何值得
每次在本地测试修改,都能省去推送、部署和查找日志的过程。Oxcart 缩短了迭代周期:docker run --rm 为 42 ms,创建并启动 20 个容器为 0.69 s,停止并移除为 77 ms,是我们测试的三款运行时中最快的。容器的出站连接由 Mac 发起,因此通往 AWS 网络的 VPN 也同样适用。
常见问题
如何在 Mac 上本地测试 ECS 或 Fargate 任务?
用 Docker Compose 运行任务的容器:每个容器定义对应一个服务,保持相同镜像、环境、端口映射、健康检查和依赖关系。docker compose up -d --wait 会在所有设有健康检查的服务都健康后返回。Oxcart 运行支持健康检查依赖和已发布端口的服务栈,让你在部署前一起验证各服务。
能在 Apple 芯片上本地运行 AWS Lambda 容器镜像吗?
可以。AWS Lambda 基础镜像包含 Runtime Interface Emulator。我们在 Oxcart 上基于 public.ecr.aws/lambda/python:3.13 构建了 Python 3.13 函数,用 -p 9000:8080 运行并用 curl 调用:它在 arm64 上原生运行,返回 HTTP 200。
LocalStack 能在 Oxcart 上使用吗?
可以,作为容器运行。我们使用 LocalStack 4.9 镜像,通过 localhost:4566 验证了 S3 存储桶创建及对象 put、get、list 操作。当前 LocalStack 版本需要 LocalStack 账户和身份验证令牌,通过 LOCALSTACK_AUTH_TOKEN 设置;未提供时最新镜像会退出。LocalStack 文档注明,ECS 从 Base 套餐起提供,EKS 从 Ultimate 套餐起提供。
如何从 Mac 将镜像推送到 Amazon ECR?
用 aws ecr get-login-password --region REGION | docker login --username AWS --password-stdin ACCOUNT.dkr.ecr.REGION.amazonaws.com 登录,然后打标签并执行 docker push。在 Oxcart 中,docker login 将密码存储在 macOS 钥匙串中。
Fargate 应构建 amd64 还是 arm64 镜像?
与任务定义的运行平台保持一致。如果使用 ARM64,就在 Mac 上构建原生 arm64 镜像;如果使用 X86_64,则用 --platform linux/amd64 构建。Oxcart 通过 Rosetta 在本地运行 amd64 镜像,让你能测试将要部署的同一镜像。
如何在 Mac 上为 EKS 开发?
用 Oxcart 在本地构建和测试应用及其依赖,再将镜像推送到 ECR。在 Mac 上用 kubectl 和 k9s 操作 EKS 集群,并在 Oxcart 上用 kwok 对本地 Kubernetes API 检查清单。参见 Mac 上的 Kubernetes 指南。
来源与方法
- 示例于 2026-10-10 使用 Oxcart 0.1.2、Mac17,14、macOS 27.2 测试(Compose、带模拟器的 Lambda 基础镜像、LocalStack 4.9 S3、Buildx)。
- LocalStack 身份验证: https://blog.localstack.cloud/localstack-single-image-next-steps/;套餐: https://localstack.cloud/pricing/;ECS: https://docs.localstack.cloud/aws/services/ecs/;EKS: https://docs.localstack.cloud/aws/services/eks/。
- Lambda Runtime Interface Emulator: https://github.com/aws/aws-lambda-runtime-interface-emulator。AWS SAM CLI 与 Docker: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-docker.html。ECS Local Container Endpoints: https://github.com/awslabs/amazon-ecs-local-container-endpoints。核实日期:2026-10-10。
- 容器速度:Oxcart 0.1.2,2026-10-10,Apple M5 Max,8 个 CPU 和 12 GiB,五次采样取中位数;其他运行时于同日较早时间,使用同一台 Mac、同一套测试工具和 docker 29.4 客户端测量。