CircleCI 2.0の処理をAWS CodeBuildで実行する

弊社では、基本的にどのプロジェクトでも CircleCI を利用して、 CI/CD を行っている。
ただ、お客様によっては、AWS環境で CI/CD も完結させたいというご要望もある。
今回は、普段 CircleCI で行っている CI/CD を、 AWS CodeBuild を使って行う場合の注意点をまとめてみる。

前提

今回の前提条件としては下記のとおりとなっている。

  • 開発環境は、 docker-compose で、アプリ用コンテナ、DB用コンテナなど複数のコンテナを使って開発を行っている
  • CircleCI でも、複数のコンテナを使って、テストをしている
  • AWS CodeBuild でも複数コンテナを使ってテストをしたい

AWS CodeBuild で複数コンテナ使いたい

CircleCI 2.0 では、Using Multiple Docker Images に記載があるとおり、

In a multi-image configuration job, all steps are executed in the container created by the first image listed. All containers run in a common network and every exposed port will be available on localhost from a primary container.

複数コンテナの設定を入れておけば、最初に定義したコンテナ内でコマンドが実行され、その他のコンテナにも最初に定義したコンテナの localhost から他のコンテナに対しても容易に接続できてしまう。

しかし、 AWS CodeBuild では、 複数コンテナの設定ができない

テスト実行に必要なミドルウェアを全部1つのコンテナにインストールしてしまい、それを使うのもありかもしれないが……。

  • コンテナのサイズが大きくなる
  • ビルドの時間がかかる
  • ちょっとした変更に弱い
  • 開発環境とは別のテスト専用のコンテナを用意する手間がかかる

などのデメリットがある。

そこで、 docker/dind イメージを使う。
dinddocker-compose をインストールして、 docker-compose を使って複数コンテナ管理&実行をしようという方法を試みた。

docker:dind

dindDocker in Docker の略。
Docker コンテナ上で、 Docker のデーモンを起動して、別の(複数の) Docker コンテナを起動できるもの。

library/docker - Docker Hub で、 dind が入っているものを使う。
今回は下記のように、 docker:dind を使うように設定した。

buildspec.ymlinstall フェーズで docker-compose インストール

docker:dinddocker-compose をインストールする。
pip をインストールして、 pip コマンドでインストール。

1
2
3
4
5
6
7
version: 0.2

phases:
install:
commands:
- apk add --no-cache py-pip
- pip install docker-compose

privileged

library/docker - Docker Hub にも注意書きがある通り、 --privileged で起動する必要があるため、 CodeBuild の管理画面でも Privileged にチェックを入れる。

Note: –privileged is required for Docker-in-Docker to function properly, but it should be used with care as it provides full access to the host environment, as explained in the relevant section of the Docker documentation.

dockerd をバックグラウンドで起動

AWS CodeBuild のカスタム Docker イメージのサンプル - AWS CodeBuild に例があるように、 install のフェーズで、バックグラウンドで dockerd を起動するようにしておく。

1
2
3
4
5
6
7
version: 0.2

phases:
install:
commands:
- nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=overlay&
- timeout -t 15 sh -c "until docker info; do echo .; sleep 1; done"

buildspec.yml

上述の手順をまとめると、

  • install フェーズで docker-compose をインストール、 dockerd を起動
  • pre_build フェーズで docker-compose build 実行して、テストに必要な複数のコンテナをビルド
  • build フェーズで docker-compose run にてテスト実行

という形になる。
buildspec.yml は下記のようになった。

1
2
3
4
5
6
7
8
9
10
11
12
13
phases:
install:
commands:
- apk add --no-cache py-pip
- pip install docker-compose
- nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay&
- timeout -t 15 sh -c "until docker info; do echo .; sleep 1; done"
pre_build:
commands:
- docker-compose build
build:
commands:
- docker-compose run app yarn test

参考URL

library/docker - Docker Hub
AWS CodeBuild のカスタム Docker イメージのサンプル - AWS CodeBuild
dind(Docker in Docker)で複数のdocker-composeを管理する · tehepero note(・ω<) 2.0

このエントリーをはてなブックマークに追加