0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

4.Lambda・APIGateway・DynamoDBで構築した環境をDocker化(GitHub Actionsを用いて)

Last updated at Posted at 2026-02-01

前回からの続きで下記内容を進める
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)をコピーしてください。

image.png

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でビルドされた「コンテナそのもの」です。
image.png

② Lambda(実行環境)

場所: AWSコンソール > Lambda > lambda-memo-api-docker-MemoFunction-...

確認ポイント:

[イメージ] タブ: 以前のZip版では「コード」が見えましたが、今回は 「イメージのURI」 が表示されています。

コードプレビューは利用できません: Docker版ではコンソール上でコードを直接編集できません。これが「不変(Immutable)なインフラ」の証拠。
image.png

③ API Gateway(動作確認)

1. 「URL」を確認する手順

  • AWSコンソールで API Gateway を開きます。

  • lambda-memo-api-docker(またはあなたが付けた名前)というAPIがある。クリックします。

  • 左側メニューの [ステージ] をクリック。

  • ステージリスト(通常は Prod )を選択します。クリックを進めていきGET内の「URL の呼び出し」(https://〜.execute-api.ap-northeast-1.amazonaws.com/Prod/)をコピーします。
    image.png

2. 実際にアクセスして「Dockerの反応」を見る

※Dockerの中で動いている Node.js が反応して、DynamoDBのデータを返せば、全システムが繋がっている証拠です!

方法A:ブラウザで確認(GETのみ)
コピーしたURLをブラウザの検索欄に貼り付けて実行してください。 例:https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/memo

下記のように[ ]が確認できるはずです!(中身が何もないため空が表示される)
image.png

方法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

実際の実行結果
image.png


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が受け取る名前と異なっていた。
image.png
<解決策>
template.yaml を修正する
template.yaml 側のキー名を index.js に合わせた。
<調査方法>
CloudWatch のLog management →ロググループでエラー箇所を確認。
CloudWatch LogsとLambdaコンソールを突き合わせて原因を特定した。


・CloudWatch上でリクエストを確認

意図したエンドポイントに到達:"path":"/Prod/memo"
リクエストが正しく受信している:"httpMethod":"GET"

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?