aws cdkaws ecrdocker2025/4/18 • 読了時間:6分

aws cdk内でecrを作成しdocker imageをpushする

ブログ記事のメイン画像

前置き

Next.jsでaws lambda × cloud frontのサーバレス構成にした際にLambda Web Adapterを使ったのですが、その際にdocker周りの動きで詰まった備忘録です。

実装についてはTypeScriptで記載しています。 環境構築などは出来ているものとして書いているので構築方法などは割愛しています。

ゴール

以下の状態とすることを最終的なゴールとします。

  • aws cdkの処理内でdocker buildができる
  • buildした成果物をaws ecrにpushする

実装

dockerファイルの作成

実際にプロジェクトを運用したときのことを考え以下のフォルダ構成で実装していきます。 先にECRにpushする簡易的なdockerファイルを作成します。

powershell
1root
2├ docker
3│ └ Dockerfile
4└aws
5(aws cdkのプロジェクト)

dockerファイルは以下の通り、expressサーバーを立ち上げて「Hello World」を返すだけの実装をしています。

powershell
1FROM node:20-alpine
2
3WORKDIR /app
4
5RUN echo '{ \
6  "name": "app", \
7  "version": "1.0.0", \
8  "description": "Simple Node.js application", \
9  "main": "index.js", \
10  "scripts": { \
11    "start": "node index.js" \
12  }, \
13  "dependencies": { \
14    "express": "^4.18.2" \
15  } \
16}' > package.json
17
18RUN npm install --omit=dev
19
20RUN echo 'const express = require("express"); \
21const app = express(); \
22const port = process.env.PORT || 8080; \
23\
24app.get("/", (req, res) => { \
25  res.send("Hello World!"); \
26}); \
27\
28app.listen(port, () => { \
29  console.log(`Server running at http://localhost:${port}`); \
30});' > index.js
31
32EXPOSE 8080
33
34CMD ["node", "index.js"]

プロジェクトの作成

次にawsフォルダ内にcdkプロジェクトを作成します。 以降はこのプロジェクト内で作業を行います。

powershell
1cd aws
2npx cdk init app --language typescript

AWSへデプロイするための準備

プロジェクトを作成した直後の状態だとAWSへの適用ができません。 「/bin/〇〇.ts」で環境情報を設定する必要があるので調整を行います。 ※〇〇はプロジェクトの作成時に指定したフォルダ名とかになっているはず

typescript
1#!/usr/bin/env node
2import * as cdk from 'aws-cdk-lib';
3import { TestStack } from '../lib/test-stack';
4
5const app = new cdk.App();
6new TestStack(app, 'TestStack', {
7  env: {
8    account: 'aws account id', // AWS認証情報
9    region: 'ap-northeast-1',
10  },
11});
12

次にpackage.jsonに以下のscriptを追加します。

typescript
1{
2  ...,
3  "scripts": {
4    "build": "tsc",
5    "watch": "tsc -w",
6    "test": "jest",
7    "cdk": "cdk",
8+    "cdk:deploy": "cdk deploy", // これと
9+   "cdk:destroy": "cdk destroy" // これ
10  },
11  ...,
12}
13

上記の実装が終わったら次のコマンドを実行します。

powershell
1npm run cdk:deploy

コマンド実行後AWSコンソールへログインを行い「CloudFormation」にスタックが作成されていれば準備完了です。

画像

AWS ECRにCDK上からDocker Imageをデプロイするpackageの追加

必要なライブラリを追加します。

powershell
1npm install --save-dev cdk-ecr-deployment

AWS ECRを構築するプログラムの実装

「/lib/〇〇-stack.ts」にてAWS環境を構築するためのプログラムを実装するファイルがあるため、ECRを構築するための実装を行います。

typescript
1import * as cdk from 'aws-cdk-lib';
2import { Construct } from 'constructs';
3import * as ecr from 'aws-cdk-lib/aws-ecr';
4import * as assets from 'aws-cdk-lib/aws-ecr-assets';
5import * as ecrdeploy from 'cdk-ecr-deployment';
6
7export class TestStack extends cdk.Stack {
8  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
9    super(scope, id, props);
10
11		// ECRリポジトリの作成
12    const repository = new ecr.Repository(this, `Repository`, {
13      repositoryName: `test-app`,
14      removalPolicy: cdk.RemovalPolicy.DESTROY,
15      emptyOnDelete: true
16    });
17
18    repository.addLifecycleRule({ maxImageCount: 3 });
19
20    // **CDK が ECR にプッシュする Docker イメージをビルド**
21    const dockerImage = new assets.DockerImageAsset(this, `Image`, {
22      directory: '../', // Docker ビルドの `context` を指定
23      file: 'docker/Dockerfile', // 使用する `Dockerfile`
24    });
25
26    // **ECR に `docker push` する**
27    const ecrDeployment = new ecrdeploy.ECRDeployment(this, `ECRDeployment`, {
28      src: new ecrdeploy.DockerImageName(dockerImage.imageUri),
29      dest: new ecrdeploy.DockerImageName(`${repository.repositoryUri}:latest`),
30    });    
31  }
32}

dockerignoreの作成

現在の状態でCDKを用いてアップする処理の実装は終わっているのですが、このまま実行するとcdk.outディレクトリ(cdkが作成するフォルダ)が無限ループで生成されるため不要なファイルをdockerにbuildから除外するようにします。

ルートディレクトリに「.dockerignore」を作成し以下の内容で実装します。

plain text
1# `context: ../` の場合、以下のフォルダを無視
2aws/
3# docker/
4cdk.out/

デプロイ&ECRの確認

以上でCDKの実装とdocker周りの調整が終わりです。 デプロイしてECRにdocker imageがpushされているか確認してみます。

powershell
1npm run cdk:deploy

デプロイが終わったら対象のスタックを選択しリソース⇒Repository⇒物理IDをクリックしECRを確認します。

画像

以下の画像の通り実行時刻でイメージが作成されていれば正常にデプロイが出来てる状態になります。

画像

終わり

以上で「aws cdk内でecrを作成しdocker imageをpushする」実装が出来ました。

EC2とかで使うかもしれない?ですが、私はAWS Lambdaでdocker imageを使って起動する方法で利用しました。

これとci cdを組み合わせてdocker imageを更新するみたいなこともできるので検討していただければと思います。

 

 

最新の記事

AIでの開発にいろいろと進展がある中、私もAIでフロントエンド実装をしてみた!となりいろいろとやって挫折した話になります。...

生成系AIの発展が目まぐるしい中、どんなことが出来るのか試してみたく実際に作ることにしました。 最後まで作り終える前にまたトレンドが変わっそうな気もしますが、気長にやっていきます。以下の工程全てAIを...