前回からの続きで下記内容を進める
4️⃣ 同アプリをDocker化
ディレクトリ構成の変更
前回作成した、Zip版を別のフォルダへ移動・Docker版のフォルダを作成する
lambda-api/
├── .github/workflows/deploy.yml <-- 自動デプロイの手順書(ここも修正が必要)
├── zip-version/ <-- 以前作ったZip版をここに移動
│ ├── index.js
│ ├── package.json
│ ├── package-lock.json
│ ├── template.yaml
│ └── samconfig.toml
└── docker-version/ <-- 新規作成
├── index.js
├── package.json
├── package-lock.json
├── Dockerfile <-- 新規作成
├── template.yaml <-- コピー済み(後で編集)
└── samconfig.toml <-- コピー済み(後で編集)
1. フォルダの作成
まずは2つのディレクトリを作成します。
mkdir zip-version, docker-version
2. 既存ファイル(Zip版)の移動
今までルートにあったファイルを zip-version に移動します。
Move-Item index.js, template.yaml, samconfig.toml, package*.json -Destination zip-version/
3. Docker版へのコピーと作成
Zip版の中身をベースに、docker-version を作ります。
Copy-Item zip-version/template.yaml, zip-version/samconfig.toml, zip-version/index.js, zip-bersion/package*.json -Destination docker-version/
docker-version/template.yaml の修正
「Zipファイルを送る」指示から「Dockerイメージを作る」指示へ変更します。
変更前
Resources:
MemoFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: . ⇚ここを消す
Handler: index.handler ⇚ここを消す
Runtime: nodejs20.x ⇚ここを消す
Events:
ApiEvent:
Type: Api
Properties:
Path: /memo
Method: ANY
Environment: ⇚ここより下を消す
Variables:
MEMO_TABLE_NAME: !Ref MemoTable
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref MemoTable
変更後
Resources:
MemoFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image # ←ここをImageに変更
Architectures:
- x86_64
# --- 環境変数の設定 ---
Environment:
Variables:
TABLE_NAME: !Ref MemoTable # MemoTableというリソースの名前を環境変数にセット
# --- DynamoDBへのアクセス権限 ---
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref MemoTable
Events:
ApiEvent:
Type: Api
Properties:
Path: /memo
Method: ANY
Metadata:
DockerContext: . # Dockerfileがある場所
Dockerfile: Dockerfile # 使うファイル名
コンテナ化に伴い、GitHub Actionsの手順に一つだけ「イメージの保存先(ECR)」に関する準備が必要。
AWS側に「イメージの倉庫 (ECR)」を作る
作成方法
-
AWSコンソールで ECR を開き、[リポジトリを作成] をクリック。
-
リポジトリ名: lambda-api-repo (何でも良いですが、メモしておいてください)。
-
そのまま [リポジトリを作成]。
-
作成後、表示される URI(例: アカウント番号.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-api-repo)をコピーしてください。
docker-version/samconfig.toml の修正
「別のアプリ」として認識させるために名前を変え、イメージの「保管場所」を教えます。
Ini, TOML
[default.deploy.parameters]
# --- 修正ポイント1: スタック名を変える (重要!) ---
stack_name = "lambda-memo-api-docker"
# --- 修正ポイント2: ECRのURLを追記 ---
# AWSコンソールで作ったECRのURIを貼り付けてください
# 個別の関数に対しても指定しておくと確実です
image_repositories = ["MemoFunction=アカウント番号.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-api-repo"]
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
# ...その他の設定(profileなどは削除したままでOK)
.github/workflows/deploy.yml の修正
GitHub Actionsが、ルートではなく docker-version フォルダの中身を使ってビルドするように指示します。
- name: Build and Deploy
# --- 修正ポイント: 作業ディレクトリを指定 ---
working-directory: ./docker-version
run: |
sam build
sam deploy --no-confirm-changeset --no-fail-on-empty-changeset
Dockerfileを作成
ファイルを作成
mkdir .\docker-version\Dockerfile
Dockerfileの中身を編集
# 1. ベースとなるイメージ(AWSが提供するLambda専用のNode.jsイメージ)
FROM public.ecr.aws/lambda/nodejs:20
# 2. プログラムを配置するディレクトリへ移動
WORKDIR ${LAMBDA_TASK_ROOT}
# 3. 依存関係(package.jsonなど)をコピーしてインストール
COPY package*.json ./
RUN npm install
# 4. プログラム本体(index.js)をコピー
COPY index.js ./
# 5. 実行する関数を指定(ファイル名.関数名)
CMD [ "index.handler" ]
ここで、Docker版をpush
GitHub上のAction(SAM Deploy)がDisable workflowであればEnable workflowにする
git add .
git commit -m "feat: complete docker version configuration"
git push origin main
本当にDockerで動いているのか?の確認
Docker要素の確認方法
AWSコンソールで以下の3箇所をチェック。
① ECR(イメージの倉庫)
-
場所: AWSコンソール > Elastic Container Registry (ECR) > lambda-api-repo
-
確認ポイント: イメージが保存されているはずです。
-
「イメージタグ」に latest や、デプロイ時の長い英数字(コミットハッシュなど)があれば成功です。
これこそが、
GitHub Actionsでビルドされた「コンテナそのもの」です。

② Lambda(実行環境)
場所: AWSコンソール > Lambda > lambda-memo-api-docker-MemoFunction-...
確認ポイント:
[イメージ] タブ: 以前のZip版では「コード」が見えましたが、今回は 「イメージのURI」 が表示されています。
コードプレビューは利用できません: Docker版ではコンソール上でコードを直接編集できません。これが「不変(Immutable)なインフラ」の証拠。

③ API Gateway(動作確認)
1. 「URL」を確認する手順
-
AWSコンソールで API Gateway を開きます。
-
lambda-memo-api-docker(またはあなたが付けた名前)というAPIがある。クリックします。
-
左側メニューの [ステージ] をクリック。
-
ステージリスト(通常は Prod )を選択します。クリックを進めていきGET内の「URL の呼び出し」(https://〜.execute-api.ap-northeast-1.amazonaws.com/Prod/)をコピーします。

2. 実際にアクセスして「Dockerの反応」を見る
※Dockerの中で動いている Node.js が反応して、DynamoDBのデータを返せば、全システムが繋がっている証拠です!
方法A:ブラウザで確認(GETのみ)
コピーしたURLをブラウザの検索欄に貼り付けて実行してください。 例:https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/memo
下記のように[ ]が確認できるはずです!(中身が何もないため空が表示される)

方法B:PowerShellで確認(データ送信も試す)
コンテナ版にデータを書き込む
今はテーブルが空っぽなので、PowerShellから1件データを追加して、コンテナ版が正しく「書き込み」もできるか確認する。
# 新しいURLをセット(自分のURLに書き換えてください)
$URL = "https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/memo"
# データをPOST送信(Docker経由でDynamoDBへ保存されるか?)
Invoke-RestMethod -Uri $URL -Method Post -Body '{"id": "docker-test", "content": "Docker版からこんにちは!"}' -ContentType "application/json"
# データを取得(保存されたものが返ってくるか?)
Invoke-RestMethod -Uri $URL -Method Get
3. ここで何が起きているのか?(裏側の動き)
API Gateway がリクエストを受け取る。(URLでGetした・ShellでPostした)
↓
AWSが ECR(倉庫) からあなたの Dockerイメージ を取り出す。
↓
そのイメージを元に コンテナを起動 する。
↓
コンテナ内の Node.js が起動し、index.js の handler が実行される。
↓
Node.jsが DynamoDB に通信し、データを読み書きする。
↓
結果をAPI Gateway経由であなたの画面に返す。
デプロイ後のリソース削除方法
自分のPCのターミナルから削除
sam delete --stack-name lambda-memo-api-docker
※スタック名は、samconfig.toml に記載した名前です。 ※「Are you sure you want to delete...」と聞かれるので y を入力します。
構築メモ
・構築時のエラー発生箇所
<事象>
環境変数名の不一致によるエラーがでて500エラーがでた。
template.yaml (渡す側): TABLE_NAME という名前で渡している。
index.js (受け取る側): MEMO_TABLE_NAME という名前で探している。
受け取る側が MEMO_TABLE_NAME を探しにいった結果、そんな名前の変数は存在しないので null (または undefined) になり、今回のエラーが発生した。
<原因>
Lambdaに設定されている環境変数がindex.jsが受け取る名前と異なっていた。

<解決策>
template.yaml を修正する
template.yaml 側のキー名を index.js に合わせた。
<調査方法>
CloudWatch のLog management →ロググループでエラー箇所を確認。
CloudWatch LogsとLambdaコンソールを突き合わせて原因を特定した。
・CloudWatch上でリクエストを確認
意図したエンドポイントに到達:"path":"/Prod/memo"
リクエストが正しく受信している:"httpMethod":"GET"


