読者です 読者をやめる 読者になる 読者になる

怠惰のすゝめ。Docker Hubで実現する効率的なチーム開発

こんにちは、2014年新卒エンジニアの進藤です。

 

ここ最近注目を集めていた Docker ですが、先日の Docker 正式版のリリースと Docker Hubの発表で、ますます盛り上がりをみせてきました。Docker の導入を本気で検討しているエンジニア・開発部署も増えてきていることでしょう。

 

今後、Docker を基盤としたアプリケーションの開発・ビルド・デプロイが当たり前の技術になるかもしれません。Dockerの技術を追いかけるように意識しておきましょう。

 

前置きが長くなりましたが、今回の記事は、Docker Hubを使ったチーム開発の話です。

Dockerの導入を検討しているエンジニア・開発部署に有意義な話ができれば、と思います。

 

チーム開発にDocker Hub を取り入れる

本題に入る前に、いま僕が進めているプロジェクトを紹介します。

開発中のプロジェクトに対して、環境構築・テスト・デプロイの自動化を進め、開発のサイクルを早める仕組み・体制を整えているところです。さらには運用中のプロジェクトに対して「Immutable Infrastructure」の概念を取り入れ、安全な運用体制についても調査・検討をしています。

 

Dockerの調査・検討に関しては記事にまとめているので、こちらもどうぞ。

怠惰のすゝめ。Dockerで環境構築・テスト・デプロイを完全自動化

 

そして先日、Docker Hubが発表されたので、Docker Hubをさっそく開発フローに組み込んで検証をしました。

検証の段階ですが、手元での動作確認は終えています。以下の開発フローを構築しました。

① Gitリポジトリにプッシュが行われる

② Automated Builds (Dockerのビルド) が行われる

③ ビルド完了後、Jenkinsに通知する

④ ビルド & 単体テストを行う

⑤ Automated Buildsで作成されたイメージをもとにコンテナを起動する

Tomcatを起動する

 

 

上の図では、Docker Hubの役割が見えづらいので、これから説明をします。

 

Docker Hub が担う役割

Docker社の公式ブログによると、Docker Hub は次の機能を備えたサービスだと説明されています。

 

・Dockerイメージの集積・管理

・Public/Privateリポジトリを通して、アプリケショーンを管理・共有する

リポジトリ管理ツール(GitHub/Bitbucket)と連係し、リポジトリの更新を検知し自動ビルド

・Webフック機能による、任意のサービス(Jenkins/Chef)と連携

 

これらの機能によって、ビルド・テスト・デプロイの一連の継続的インテグレーションと継続的デプロイを実現することが可能になります。

 

 

それでは、先ほど紹介した開発フローについて、Docker Hubの役割を具体的に見てきましょう。

 

 

① Automated Builds

  Gitリポジトリ (Dockerfile含む) が更新されると、Automated Builds が行われます。

  Docker Hub が Git リポジトリの更新を自動で察知して、ビルドを始めます。

② Dockerfileをビルド

  GitリポジトリにあるDockerfileをビルドして、イメージを作成します。

③ イメージをリポジトリにPush

  Dockerfileのビルドで作成されたイメージを、Docker Hub のリポジトリにPushします。

④ Webフック

  Webフックを利用して、Jenkinsと連携をします。

 

 

Docker Hubの導入により開発フローが複雑になったかのように見えるかもしれませんが、上記の手順②と③は Docker Hubが自動で行い、手順①と④は簡単な設定のみです。

 

とはいうものの、Docker Hubの導入コストについて気になる方も多いと思いますので、次はDocker Hubの導入コストと、メリットについて説明をします。

 

Docker Hubの導入コストと得られるメリット

この記事を読んでるエンジニアの中には、Github と Jenkins を連携させてチーム開発を今まさにしているという方もいると思います。そこに Docker Hubが発表され、Docker Hubの導入を検討しているなかで、導入コストとメリットは気になるところでしょう。

 

既存の開発フローに Docker Hubを導入する手順としては、大きく分けて次の3つです。

1. 対象プロジェクトの Github リポジトリに Dockerfile を追加する

2. Docker Hub の管理画面から、対象プロジェクトの Github リポジトリと連携させる

3. JenkinsなどのCIツールと連携させる場合は、Docker Hub の管理画面から設定する

 

どうでしょうか。イメージはまだつかめないかもしれませんが、既にあるプロジェクトに対しても、少ないコストで導入することができるのは感じ取れるのではないでしょうか。具体的な導入方法については後述します。

 

 

得られるメリットですが、個人的には、環境設定が記述されている Dockerfile をどこで管理して、どのように使うかを示してくれたことが大きいと思っています。環境設定に関するドキュメントやイメージをどこで管理すべきか悩んでるシステム管理者は多いのではないでしょうか。Docker社はその一つの解として、ドキュメントをGithubリポジトリとして管理し、イメージはDockerhubリポジトリで管理することを提案しました。

 

その他にも、当たり前のことですが、Dockerfileをリポジトリ管理して、ボタン一つでいつも同じ環境を作れるということは、チームのみんなが全く同じ環境で開発・運用をすることを可能にします。「その不具合、ぼくの環境では起きていないよ」と不毛な争いをすることも少なくなるのではないでしょうか。また、プロジェクトのソースコードと環境設定が紐づけられることで、ローカルで開発したものが本番サーバーで動かないという現象もなくなります。

 

少ない導入コストで得られるメリットが大きいのではないでしょうか。チーム開発が円滑に行われるのが容易に想像できます。では次に、具体的な Docker Hub導入手順を紹介します。

 

Docker Hub導入手順

ここでは、Tomcatで "Hello World!" のページが表示されるサンプルコードを使って、実際に Docker Hub を導入してみます。

 

サンプルコードは以下のURLに置いています。warファイルを作成して、Tomcatにデプロイすれば "HelloWorld" が表示されます。warファイルの作成には、Gradleを使っています。

 

Githubリポジトリ

https://github.com/Taichi-SHINDO/dockerhub_sample

 

Dockerhubリポジトリ

https://registry.hub.docker.com/u/cyndow/dockerhub-sample/builds_history/28572/

 

$ wget https://github.com/Taichi-SHINDO/dockerhub_sample/archive/master.zip

$ unzip -o master.zip

$ cd dockerhub_sample-master/

$ gradle build

$ mv hello.war ${TOMCAT_DIR}/webapps/

http://localhost:8080/hello/index で "Hello World!" が表示されるページが見れます。

 

 

1. 対象プロジェクトの Github リポジトリに Dockerfile を追加する

 

 

2. Docker Hub の管理画面から、対象プロジェクトの Github リポジトリと連携させる

 

Docker Hub の画面から、Automated Builds を選択する

 

 

Docker Hub を導入する対象プロジェクトを選択する

 

 

Dockerfileの場所やタグ、Public/Privateリポジトリの選択をチェックして、問題なければリポジトリを作成する。

 

 

リポジトリ作成後にビルドが走る

 

 

3. JenkinsなどのCIツールと連携させる場合は、Docker Hub の管理画面から設定する

 

Webhooksを選択

 

 

Hook URLに ${JenkinsのジョブURL}/build? を登録する (例: http://○○.○○.○○.○○/job/docker-sample/build?)

 

 

登録後に、Test Hook を選択してみましょう。

Jenkinsの画面でビルドが行われていたら成功です。

 

 

あとは、Jenkinsのジョブで、テスト/デプロイが行われるように設定をすれば完了です。各自の環境に合わせて設定してください。

今回は、JenkinsとDockerが同じサーバーにあるとして、次のシェルが実行されるように登録しました。

 

sudo service docker restart

sudo wget https://github.com/Taichi-SHINDO/dockerhub_sample/archive/master.zip

sudo unzip -o master.zip

cd dockerhub_sample-master/

sudo /home/ec2-user/tools/gradle-1.12/bin/gradle build

sudo /home/ec2-user/tools/gradle-1.12/bin/gradle test

sudo /home/ec2-user/tools/gradle-1.12/bin/gradle war

sudo docker run -dit -p 8080:8080 -v /home/ec2-user/workspace/dockerhub_sample-master/hello.war:/usr/share/tomcat7/webapps/hello.war cyndow/dockerhub-sample /bin/bash

 

 

テスト・WARファイル出力については、Gradleを使っています。デプロイについては、Docker起動時にホストサーバーにあるWARファイルをマウントして、デプロイしています。

 

 

最後に

ここからは感想です。

 

Dockerを使った開発フローの調査・検討にはかなりの時間を費やしました。CyberZの開発・運用にあったものを考えることもありましたし、Docker Hub と Jenkins の連携部分はとくに悩んだ部分でした。Docker Hub は多くの場面で使用できる素晴らしいサービスです。それゆえに、どこまで Docker Hub に任せるかの線引きを必死に考えました。極端なことをいえば、CIツールを丸々 Docker Hub に任せるという考え方も無かったわけではありません。

 

そこで大事にしたのは、「チームで開発を円滑に行うためには何がいいのか」「既に動いているプロジェクトでDockerを導入するためには」ということでした。

 

JenkinsにはJenkinsの良さがあります。テスト結果をきれいなレポートとしてまとめてくれるし、何よりも使い勝手が非常に良いです。テストとの相性は抜群に優れています。今、現状で動いている Jenkins はそのままに、Jenkins で相性が悪いところを Docker Hub に任せようという考え方に落ち着きました。そうすることで、結果として、既に動いているプロジェクトに対しても少ないコストでDocker Hubを導入できることにつながりました。

 

今後もDockerからは色々な機能がでてくることでしょう。少しずつ導入していきながら、チーム開発の最適を探っていきたいと思います。