このエントリーは、Atlassian Advent Calendar 2015 - Qiitaの7日目のエントリーです。
docker-composeによるCI環境上でのコンテナー間の連携
昨日のAtlassian Community Day 2015 | Peatixで、弊社グロースエクスパートナーズより、「Atlassian Summit 2015でのDevOps関連の取り組みについて」というテーマで講演致しましたが、その中で取り上げたdocker-composeの連携のデモについてこのエントリーでは紹介します。
CI界隈では「ポータブルなビルド」という言い方がされます、これはビルドをするために必要な環境の情報をDocker等を使用して構成管理の下に置くことで、ビルドの環境をBambooやJenkinsなどのCIサーバー上の環境とは疎結合にして、ビルドの独立性、安定性、スケーラービリティーを得ることを目的にしています。
コンテナー上でビルドを行う際に、ビルドのプロセスが単独で完結していればいいのですが、データベースなどの外部のサーバープロセスとの連携が必要になる場合もあります。そのための方法はいくつかありますが、ここではdokcer-composeを用いてコンテナ間の連携を行います。
このデモはAtlassian SummitのSummit 2015 - Docker, Continuous Integration, and You | Atlassianというセッションで紹介されたものの改良版で、外部コンテナーとしてPostgreSQLとElasticsearchを起動して連携しています。
デモレポジトリについて
- DockerのPostgreSQLイメージのスキーマ初期化の仕様がかわったのでそれの対応
- デモが作成された当時は
docker-compose
がDockerに統合されておらずfig
だったため、fig.yml
をdocker-compose.yml
にリネーム - 依存ライブラリを毎回ダウンロードしていてビルドに時間がかかるので、ローカル環境でキャッシュするようにした
という点に手を加えています。
Bambooの設定について
Bambooは以下のような構成になっています。
docker-compposeのセットアップ
まずGitからコードを取得した後の、最初のステップはdocker-compose
のセットアップになります。予めBambooサーバー上にdocker-compose
がセットアップされている場合は不要です。
curl -L https://github.com/docker/compose/releases/download/1.2.0/docker-compose-Linux-x86_64 > docker-compose chmod +x docker-compose
ディレクトリの初期化
次のステップは依存性をキャッシュするディレクトリの初期化になります。
mkdir -p target/.m2 mkdir -p target/.lein
docker-composeによるビルド
set -x sudo ./docker-compose kill sudo ./docker-compose rm --force sudo ./docker-compose build sudo ./docker-compose up
この中では、docker-compose.ymlの設定にしたがってelasticsearchとPostgreSQLのイメージを起動し、次にDockerfileに従ってアプリケーションのビルドを行っています。この際に、EXPOSEしているポートがオープンになるのとサーバーのプロセスがreadyになるのにタイムタグがあってたまにビルドがこけるので、ポートをポーリングするスクリプトを使ってコンテナの中のポートが立ち上がるのを待つようにしています。
ビルド結果の取得
CID=`sudo ./docker-compose ps -q transfer` sudo docker cp ${CID}:/code/testreports.xml . sudo chown bamboo:bamboo testreports.xml sudo docker cp ${CID}:/home/transfer/.m2 target/ sudo docker cp ${CID}:/home/transfer/.lein target/ sudo chown -R bamboo:bamboo target/
後処理としてDockerからテスト結果のxml(JUnit形式)ならびに依存性キャッシュをコンテナーからコピーする段取りになります。ここでコンテナーから取得した依存性のキャッシュを次回のビルドの時に戻すことによって、ビルド時間を節約しています。
テスト結果のパース
前のプロセスで取得したテスト結果(testreports.xml)をここでパースしています。
CleanUp
sudo ./docker-compose kill sudo ./docker-compose rm -f
ここはコンテナの後始末になります。
ビルド結果
はまりどころ
- PostgreSQLのDockerイメージの仕様変更でビルドが走らなくなっていたため、発表の前日にデバッグしていたこと
- Macbook ProのVagrant上でBamboo+Dockerを動かしていたのですが、最初CPU×2、メモリ2Gにしたらelasticsearchにリアルタイム連携しているところが間に合わなくてテストがfailしたこと。CPU×3、メモリ4Gにしたら動いた。
最後に
Bamboo+docker-composeによるCIビルドの例でした。Atlassian Summitの事例報告と言うことでBambooを使った発表になりましたが、Bambooの特定機能には依存していないので、CIサーバーでのDockerの使用例の一つとしてみていただければと思います。