はじめに
AWS Lambda はデプロイして実行するまでに時間がかかるので、ローカルで素早く挙動を確かめたくなり、public.ecr.aws/lambda/provided:al2.2025.10.04.11を使った最小構成を local-lambda リポジトリにまとめました。
(https://docs.aws.amazon.com/lambda/latest/dg/images-test.html)
(https://github.com/yuki-miyakawa/local-lambda)
multi-stage build での Go バイナリ配置と Runtime API の観測ポイントをこの記事で整理します。
(https://docs.aws.amazon.com/lambda/latest/dg/runtimes-images.html)
環境構築の準備
今回のリポジトリは Docker さえあれば動きます。Docker 環境は Colima を使用しています。Go や AWS CLI はコンテナ内で完結するので、手元には Docker とjq(レスポンス確認用)が入っていれば OK です。起動直後にバージョンチェックだけ通しておきます。
docker --version
jq --version
前提ツールとディレクトリ構成
リポジトリ直下の主なファイルは以下の通りです。
-
Dockerfile: Go 公式イメージでビルドしたbootstrapを provided ベースの 2 段階目にコピー -
Makefile:make docker-build→make run→make invokeで一連の操作を自動化 -
cmd/handler/main.go: Lambda ハンドラー本体 -
event.json: 動作確認用リクエストペイロード
multi-stage build でbootstrapを作るため、ローカルに Go をインストールしていなくてもビルドできます。
コンテナで Lambda を動かす
provided:al2.2025.10.04.11イメージに multi-stage で作成したbootstrapを配置すると Runtime API をそのまま呼び出せます。(https://docs.aws.amazon.com/lambda/latest/dg/images-create.html)
今回使った Makefile と Dockerfile を載せます。
APP_NAME ?= local-lambda
IMAGE_NAME ?= $(APP_NAME):latest
ARCH ?= arm64
.PHONY: docker-build
docker-build:
docker build --build-arg TARGETARCH=$(ARCH) -t $(IMAGE_NAME) .
.PHONY: run
run:
docker run --rm -p 9000:8080 $(IMAGE_NAME)
.PHONY: invoke
invoke:
curl -s -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" \
-H 'Content-Type: application/json' \
-d @event.json | jq
# Build the Go bootstrap binary
ARG TARGETOS=linux
ARG TARGETARCH=arm64
FROM public.ecr.aws/docker/library/golang:tip-trixie AS builder
WORKDIR /src
COPY go.mod ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o bootstrap ./cmd/handler
# Package the bootstrap into the provided.al2 base image
FROM public.ecr.aws/lambda/provided:al2.2025.10.04.11
COPY --from=builder /src/bootstrap /var/runtime/bootstrap
CMD ["bootstrap"]
package main
import (
"context"
"github.com/aws/aws-lambda-go/lambda"
)
type Request struct {
Name string `json:"name"`
Age int `json:"age"`
Job string `json:"job"`
Gender string `json:"gender"`
}
type Response struct {
Name string `json:"name"`
Age int `json:"age"`
Job string `json:"job"`
Gender string `json:"gender"`
}
func handler(ctx context.Context, req Request) (Response, error) {
res := Response(req)
return res, nil
}
func main() { lambda.Start(handler) }
テストイベントはevent.jsonに置いてあるものを使用します。
{
"name": "John Doe",
"age": 21,
"job": "Developer",
"gender": "Male"
}
コンテナのビルドから実行、イベント送信までをワンコマンドで回すと次の流れになります。
make docker-build # multi-stageでbootstrapをビルド
make run # ポート9000でLambda Runtime APIが待ち受け開始
make invoke # event.jsonを投げてレスポンスをjq整形
動作確認と検証のポイント
Runtime API はポート 9000 で待ち受けるので、別ターミナルからイベントを投げてログを比べます。
curl -s -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" \
-H 'Content-Type: application/json' \
-d @event.json | jq
ログはmake runプロセスをフォアグラウンドで動かしているターミナルで確認可能です。
使用メモリ量は常に最大メモリ量が表示されてしまうので、メモリのカスタマイズは実際に AWS Lambda にデプロイし調整する必要があります。
19 Oct 2025 23:47:35,371 [INFO] (rapid) INVOKE START(requestId: 455cb184-a434-459e-8bea-6189872f27ba)
END RequestId: 455cb184-a434-459e-8bea-6189872f27ba
REPORT RequestId: 455cb184-a434-459e-8bea-6189872f27ba Init Duration: 0.19 ms Duration: 5.95 ms Billed Duration: 6 ms Memory Size: 3008 MB Max Memory Used: 3008 MB
19 Oct 2025 23:47:35,372 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.624000ms)
| 観点 | コンテナログ | Lambda 本番ログ |
|---|---|---|
| 取得方法 | docker logs で直接取得 | CloudWatch Logs が自動収集 |
| 主な用途 | 開発時のデバッグ | 運用監視とアラート |
| 実行環境 | Docker Engine 上で provided.al2 | マネージドな provided.al2 |
トラブルシューティングと応用
- アーキテクチャ差異:
exec format errorが出たときはARCH=amd64 make docker-buildのようにARCHを指定し直すと解消します。 - 依存キャッシュ:
go mod downloadは multi-stage の先頭で実行しているので、Go の依存を変えた際はdocker build --no-cache ...でキャッシュを飛ばすと早いです。(https://docs.aws.amazon.com/lambda/latest/dg/images-troubleshoot.html)
まとめ
provided.al2.2025.10.04.11 コンテナで Go バイナリを multi-stage build し、Runtime API を手元で叩けることを確認しました。(https://docs.aws.amazon.com/lambda/latest/dg/images-test.html)
今回作成した local-lambda リポジトリを fork してmake docker-build→make invokeを回すだけで安全に検証できるのでぜひ使ってみてください!(https://github.com/yuki-miyakawa/local-lambda)
今回の構成では単一の AWS Lambda の動作確認にとどまってしまうので、次は 1 つのリポジトリに複数の Lambda 関数を実装したい場合、DynamoDB を使用したい場合などを考慮した検証環境の構築を取り上げようと思います。