どこで何を動かすか
| AWSサービス | ローカルでの代替 | ローカルのワークフロー |
|---|---|---|
| ECSタスク、Fargateタスク | タスクのイメージをDocker Composeで実行 | ヘルスチェックと公開ポートを使い、サービスをまとめて実行 |
| Lambda(コンテナイメージ) | Runtime Interface Emulatorを含むLambdaベースイメージ | ネイティブarm64上でHTTP経由で関数を呼び出す |
| S3などのAWS API | LocalStack | S3のバケット・オブジェクト操作をローカルで開発 |
| EKS | kubectlとk9sで実際のクラスターへ接続、ローカルAPIにはkwok | ローカルでビルド・テスト後、kubectlとk9sでクラスターを操作 |
ECS・FargateタスクをComposeプロジェクトとして動かす
ECSタスク定義は、イメージ、環境、ポートマッピング、ヘルスチェック、起動順序を持つコンテナの一覧です。Composeも同じ内容を定義するため、コンテナ定義ごとに1つのサービスとしてそのまま対応付けられます。
| タスク定義 | 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を作成し、{"statusCode": 200, "body": "hello"}などの辞書を返すhandler(event, context)関数を定義します。 - 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 APIとExtensions APIのプロキシ」で、/2015-03-31/functions/function/invocationsエンドポイントを立ち上げます。
LocalStackでAWS APIを使う
LocalStackはポート4566の1つのコンテナで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」で終了します。無料のHobbyプランは非商用利用向けで、ECSはBaseプランから、EKSはUltimateプランから利用できます。
ECRにpushしてデプロイする
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はレジストリのパスワードを~/.docker/config.jsonではなくmacOSキーチェーンに保存します。Oxcartからのマルチプラットフォームイメージのpushは未対応です。アーキテクチャごとにタグをpushするか、CIからマルチアーキテクチャマニフェストを公開してください。
MacからEKSを使う
aws eks update-kubeconfig --name my-clusterでクラスターをkubeconfigに追加すると、macOSからkubectlやk9sを使えます。Oxcartでサービスをローカル開発・テストし、同じイメージをEKSにデプロイします。ローカルでマニフェストやコントローラーをテストする場合は、kwokが実際のKubernetes APIサーバーとシミュレートしたノードを提供します。ワークフローの組み合わせ方はMacでKubernetesを使うガイドで説明しています。
ローカルで反復する価値
変更をローカルでテストするたびに、push、デプロイ、ログ探しを省けます。Oxcartならその反復も短くなります。docker run --rmは42 ms、20コンテナの作成・起動は0.69 s、停止・削除は77 msで、テストした3つのランタイムの中で最速でした。コンテナの外向き接続はMacが開くので、AWSネットワークへのVPNも適用されます。
よくある質問
MacでECSやFargateのタスクをローカルテストするには?
Docker Composeでタスクのコンテナを実行します。コンテナ定義ごとにサービスを1つ作り、同じイメージ、環境、ポートマッピング、ヘルスチェック、依存関係を設定します。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_AUTH_TOKENに設定します。ない場合、最新イメージは終了します。LocalStackの説明では、ECSはBaseプランから、EKSはUltimateプランから利用できます。
MacからAmazon ECRにイメージをpushするには?
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にpushします。Mac上のkubectlとk9sでEKSクラスターを操作し、Oxcart上のkwokでローカルKubernetes APIに対してマニフェストを確認します。MacでKubernetesを使うガイドをご覧ください。
出典と測定方法
- 例はOxcart 0.1.2、Mac17,14、macOS 27.2で2026-10-10にテストしました(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、5回測定の中央値。他のランタイムは同日のそれ以前に、同じMacと測定ハーネスでdocker 29.4クライアントを使って測定しました。