2022年早々、AWSでコンテナを使ったWebアプリの構築を試したので、手順をまとめました。
ただコンテナを動かすだけではなく、ソースコードからコンテナイメージをビルドし、自動で最新のコンテナイメージをデプロイするフローを作りました。
下記の図のようにして構築しました。

上記の図の中から、
- CodeBuildでコンテナイメージをビルド・ECRへpush
- ECS+FargateでECRのコンテナイメージを元にコンテナを起動
- CodePipelineで、自動でECSにコンテナをデプロイ
上記3つに分け、今回は「CodeBuildでコンテナイメージをビルド・ECRへpush」について記事にまとめます。
目次
概要
今回は、下記の赤枠の部分について進めます。

ECR初期設定
まず、コンテナイメージを格納するためのECRのリポジトリを作成します。
- Amazon ECRの画面にて、「リポジトリを作成」ボタンを押します。

- 下記のように任意のリポジトリ名を入力し、「リポジトリを作成」ボタンを押します。可視性設定は、「プライベート」にします。(仕事上でパブリックにイメージを作成することは無いと思うので)

- 下記のようにリポジトリが作成できていれば完了です。

CodeCommit(GitHub)にソースコードを用意
コンテナのソースコードと、CodeBuildを動かすためのソースコードを用意します。
用意するソースコード
Dockerfile
まず、Dockerfileです。apache+phpのDockerfileを用意しました。
FROM php:7.3-alpine3.12
RUN apk update && apk add --no-cache \
# apache
apache2 apache2-ssl \
# phpパッケージ
php7-common php7-apache2 php7-ctype php7-fileinfo php7-json php7-mbstring php7-openssl \
php7-pdo php7-pdo_mysql php7-mysqli \
php7-tokenizer php7-xml php7-session \
# 追加
php7-bz2 php7-calendar php7-exif php7-gettext php7-pecl-imagick php7-pecl-mcrypt php7-pcntl php7-pdo_mysql php7-shmop php7-sockets \
php7-sysvmsg php7-sysvsem php7-sysvshm php7-wddx php7-xmlrpc php7-xsl php7-zip \
# タイムゾーン
tzdata && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
buildspec.yml
CodeBuildは、その処理をymlで記載します。
AWSの公式ページからそのままコピペで用意しました。
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -f ./docker/apache-php/Dockerfile -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
ソースコードをGitにPush
-
上記ソースコードを下記のようなディレクトリ構成で配置します。
. ├── buildspec.yml └── docker/ └── apache-php/ └── Dockerfile通常、例えば以下のように、トップディレクトリに、docker-compose.ymlなど、別のファイルやディレクトリも置くと思うので、それを考慮したディレクトリ構造としています。

-
AWSのサービスを使うのであれば、これらをCodeCommitにpushするところなのですが、今回は(すでにGitHubを使ってたので)、GitHub上のリポジトリにこれらのファイルをpushしておきます。
CodeBuild設定
初期設定
-
以下からCodeBuildのプロジェクトを作成します。

-
任意のプロジェクト名を入力します。

-
今回は、先程記載したとおり、GitHubと連携するように設定します。認証用のダイアログが表示されるので案内に従って、承認してください。

-
認証したら、リポジトリ名や対象のブランチ名を入力します。

-
下記のようにCodeBuildを実行する「環境」を設定していきます。「特権付与」はチェックしておかないとDockerイメージが作成できないのでチェックしておきます。

-
CodeBuild実行用のロールが必要なので、任意の名前で作成します。

-
CodeBuildを実行する環境のリソースも設定できます。今回は最小の構成で設定します。

-
以下で、先程「buildspec.yml」内に記載のあった環境変数を設定します。

-
先程用意したbuildspec.ymlを使うので下記ラジオボタンを選択した状態にします。ファイル名を指定することも出来ます。

-
「ビルドプロジェクトを作成する」ボタンを押すと完了です。

初期設定で追加したロールへのポリシー追加
先程作成したロールに対して、ECRを操作するポリシーを追加する必要があるので追加します。
-
IAMの管理画面から先程追加したポリシーを選択します。

-
「ポリシーをアタッチします」ボタンからポリシーを追加します。

-
「AmazonEC2ContainerRegistryPowerUser」というポリシーを検索して選択します。

-
以下のようにポリシーが設定されていれば完了です。

CodeBuild実行・ECRへのイメージのビルドの確認
-
「ビルドを開始」ボタンを押すと、作成したプロジェクトのCodeBuildの実行が開始します。

-
以下のように「成功」と表示されればビルド成功です。(写真は何回か手順を間違えたので失敗しています)

-
ECRの画面を確認すると、確かにイメージが作成出来ていることが確認できます。

これで、ECSで起動するためのコンテナイメージがの準備はできました。
あとは、これを自動化します。
CodeBuildの自動化
mainブランチにpushがあったタイミングで自動でCodeBuildが動くように設定します。
-
下記のように対象のプロジェクトの画面で、「編集」プルダウンから、「ソース」を選択します。

-
入力項目の下記部分を下記のように入力します。「イベントタイプ」を
pushにし、「HEAD_REF」に、ブランチを指定し^refs/heads/main$のように書くと、「mainブランチにpushがあったタイミング」という指定が出来ます。

-
この状態で、mainブランチにpushすると、下記のようにCodeBuildが動き出します。

自動でコンテナイメージが作れた
これで、ソースコードを用意したら自動で「CodeBuildでコンテナイメージをビルド・ECRへpush」をすることができました。
次回は「ECS+FargateでECRのコンテナイメージを元にコンテナを起動」について記事にまとめます。
