Jenkins×Capistrano3×Chef×serverspec×Dockerを使った一気通貫な開発

ここ最近、タイトルの通りのことをやろうとしていて、そのための雑記(記録)を書いていこうと思います。

目的

自動化できるところは可能な限り自動化し、テストできる(すべき)ところは可能な限りテストする、といった当たり前のことを当たり前にやって、開発業務を効率化する、というのが目的。

以下のようなアプリケーションをターゲットにします。ビルド職人、デプロイ職人への依存度を小さくし、なるべくシンプルで統一的なフローにしたいと思います。

ツールの検討

ツールは目的ではなく手段なので何でもよいのですが、Jenkins, Capistrano3, Chef, serverspec, Dockerといったツールを選ぶにあたっての評価ポイントは以下。

  • 使い慣れているかどうか
  • 情報量が多いか、公式のドキュメントが整理されているか
  • オープンソースであること(調査やカスタマイズのしやすさ)

あとは、Capistrano3、Chef、serverspecという組み合わせにすると全部Rubyで統一できるので、学習コストが低くて済むだろうと(安易に)考えました。

なお、このエントリを書いている時点では結論が出ていないので、後になってダメそうだったら別のツールを選んでいるかもしれません。逆にこなれてきたらroundsmanとかを使ってみるかも。

ツールの棲み分け

それぞれのツールは会社or自宅で使ったり試したりしているので、概要は理解しているつもりなのですが、これらのツールを一気通貫で使う場合、以下の点をきちんと考えていくことが重要だと感じます。

  • Capistrano3とChefの棲み分け
  • ChefとDockerの棲み分け
  • Capistrano3とJenkinsの棲み分け

どのツールもやろうと思えば色々できてしまうので、きちんと役割分担を考えていかなければ、ツールに使われるようになってしまうので危険(これまでの経験上)。いきなりroundsmanを使わないのも、その辺りを危惧しているためだったりします。

また、指針はあっても絶対の正解が無い部分だと思うので、プロジェクトにフィットさせていくのが腕の見せどころなのかなぁと。

DockerとChefの棲み分け

Dockerで用意するのは、「必要最低限の設定がされたイメージにする」ことを念頭に、Chefとの役割を分担します。

そうすると、Dockerがやることは、基本イメージに対して「SSHでリモートから接続できるようにする」+αくらいのことだけになるのかなぁと。とは言え、SSH接続させるためだけでも Dockerfile にユーザの追加、鍵の生成、等々が必要になるのですが…。

アプリケーションが利用するミドルウェアのインストールなんかはChefが担当します。

Capistrano3とChefの棲み分け

当初この棲み分けが頭を悩ませたのですが、capistrano-railsがやってくれることから逆算して、考えると道を大きく外すことはないかなぁと思いました。

capistrano-railsでデプロイすると、以下のあたりが実行されます(rake db:createはされないんですね)

  • アプリケーションのダウンロード
  • bundle install
  • rake assets:precompile
  • rake db:migrate
  • アプリケーションの起動・停止

cap staging deployで実際に何回かデプロイしてみると、切り戻しが簡単にできるように、デプロイ先のディレクトリで複数のアプリケーションが存在していることが分かります。

複数のバージョンを残しておくCapistranoと、冪等性によってある状態に収束させるためのChefとでは根本的に用途が違うものなんだと、理解がちょっとだけ深まりました。

最後、Docker、Capistrano3がカバーしない中間の部分はChefが担当します。
とは言え、DB作成をChefでやるのは微妙な気がするので、Capistrano3でやります(うーん…)。デプロイしないと rake db:create 実行できないですしね。

Capistrano3とJenkinsの棲み分け

ここの棲み分けはあまり悩まなかったのですが、一応考えた内容について言及。

JenkinsにもDeploy Pluginというものがありますし、Capistrano3を使わずに、デプロイツールとしてもJenkinsを使うことも可能だと思います。

「複数サーバへデプロイする」という点を取っても、例えば、Jenkinsのマルチ構成プロジェクトでできると思います。

今回の棲み分けとしては、ビルド~パッケージ作成までがJenkins、以降のデプロイはCapistrano3が担当するようにしました。

「あらゆる環境へのデプロイ方法を統一させる」という継続的デリバリーの原則からすると、開発環境へのデプロイは下のようなコマンドを実行するジョブをJenkinsで作って実行させる予定。

# cap development deploy workspace=${WORKSPACE} ... その他パラメータ