システム開発部Misocaチームエンジニアの id:mizukmb です。
Misocaチームでは、DockerイメージのビルドをAWS CodeBuildを利用して日々ビルドをしています。
CodeBuildではbuildspecと呼ばれるファイルに docker build
や docker push
といったコマンドを記述することで、CodeBuildを起動した際にこれらのコマンドを自動で実行することができます。
このbuildspecにはビルドフェーズがあり、それぞれのフェーズに適した処理を記述する事が推奨されています。この辺りを意識してDockerイメージのビルドからECRのプッシュまでをbuildspecに記述したいと思います。
ビルドフェーズとは
CodeBuildには phases/install
や phases/build
といった決められたビルドフェーズがいくつかあり、各フェーズに適したコマンドを配置する事がAWSのドキュメントにより推奨されています。
例えば phases/install
はAWSのドキュメントでは以下のように書かれています。
install フェーズは、ビルド環境でのパッケージのインストールにのみ使用することをお勧めします。たとえば、このフェーズを使用して、Mocha や RSpec などのコードテストフレームワークをインストールすることができます。
( https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html より引用 )
また、ビルドフェーズは各フェーズで成功/失敗した場合にどのフェーズに遷移するかが決められています。このフローチャートは以下のドキュメントの ビルドフェーズの移行
から確認できます。
これらを意識して書かれたbuildspecについて次の章にて解説します。
buildspec
app:latest
というタグ名のDockerイメージをビルドし、ECRにプッシュする。プッシュの前にDockerイメージの内容が期待通りであるか Gossを使ってサーバーテストを実行し、失敗したらプッシュを行わずにCodeBuildの実行を終了する。
というような処理を先ほど説明したビルドフェーズを意識して書いてみると以下のような内容になります。
version: 0.2 phases: install: commands: - curl -L https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dgoss/dgoss -o /usr/local/bin/dgoss - chmod +rx /usr/local/bin/dgoss - curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.16/goss-linux-amd64 -o /usr/local/bin/goss - export GOSS_PATH=/usr/local/bin/goss - export GOSS_FILES_PATH=config/docker/spec pre_build: commands: - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com build: on-failure: ABORT commands: - docker build -t app:latest . post_build: commands: - dgoss run app:latest - docker tag app:latest XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest - docker push XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest
それぞれのフェーズについて先ほど紹介したAWSのドキュメント CodeBuild のビルド仕様に関するリファレンス - AWS CodeBuild の内容をベースに解説します。
phases/install
install
フェーズではビルド等に必要なパッケージのインストールが推奨されています。 aws
, docker
コマンドはCodeBuild実行環境にはプリインストールされているので、このフェーズでは goss
とDockerイメージをテストするためのラッパースクリプト dgoss
をインストールします。環境変数 GOSS_PATH
と GOSS_FILES_PATH
は dgoss
の実行に必要なので一緒に設定します。
goss
と dgoss
のインストールについてはこちらのREADMEを参考にしています
install: commands: - curl -L https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dgoss/dgoss -o /usr/local/bin/dgoss - chmod +rx /usr/local/bin/dgoss - curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.16/goss-linux-amd64 -o /usr/local/bin/goss - export GOSS_PATH=/usr/local/bin/goss - export GOSS_FILES_PATH=config/docker/spec
phases/pre_build
pre_build
フェーズではビルド前に必要なコマンドを実行する事が推奨されています。ECRにサインインしておきます。
pre_build: commands: - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com
phases/build
build
フェーズではビルドを実行するコマンドを記述する事が推奨されています。今回のメインである docker build
を記述します。
docker build
が失敗してDockerイメージが作成できなかった場合、 post_build
フェーズに移行してもサーバーテストの実行やECRへのプッシュを行えないので on-failure: ABORT
を設定してビルドを中止します。
build: on-failure: ABORT commands: - docker build -t app:latest .
phases/post_build
post_build
フェーズはビルド後に行うコマンドを記述する事が推奨されています。ここではGossの実行やECRへのDockerイメージプッシュを行います。
post_build: commands: - dgoss run app:latest - docker tag app:latest XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest - docker push XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest
おわりに
ビルドフェーズを意識したDockerイメージのビルドとプッシュを行うbuildspecの書き方について書きました。CodeBuildはビルドフェーズを意識せずに例えば全てのコマンドを install
フェーズに書いても期待通りに動作します (今回でいえばECRのプッシュまで出来てしまう)。ですが、ビルドフェーズを意識することでより可読性の高く、正しく失敗するbuildspecを書く事ができます。
採用
弥生ではエンジニアを募集しています。