Dockerを使って各ブランチ毎のステージング環境を作った話 #docker #rails

こんにちは、サーバサイドエンジニアを担当しているヤマヒロです。

今回は、Dockerを使って各ブランチ毎のステージング環境を作った話について書いていきたいと思います。

なぜDockerを使ってステージング環境を作ったのか

以前はステージング環境が一つだけ存在し、各自が自分のissueが終わった段階で上げていたのですが、エンジニアの人数が増えていくにつれステージングにあげる頻度が増え、ステージングに自分のブランチを上げるタスクがスタックしていくようになってきてしまいました。

そこでチームのメンバーにアドバイスをもらい、前職でdockerを使ってステージングを作っていたので、とても便利だったからそれでやってみたらどうかということで、実際に作ってみることにしました。

Dockerを使ってステージング環境を作るまでの過程と、手間取ったこと

環境構築手順は、大まかにまとめると

  1. CapistranoでDockerコンテナに対してデプロイを出来る状態にするために必要なパッケージ・ライブラリなどが一通りインストールされた(初期環境構築が終わった)imageを作る
  2. 1で作成したimageをベースに現在のブランチ名が付けられたコンテナを作成し、Capistranoでそのコンテナに対してデプロイするシェルスクリプトを書く
  3. 作成されたコンテナの中で使用済みのコンテナを定期的に削除するシェルスクリプトを書く

の手順で進めていきました。

imageの作成に関しては、パッケージ・ライブラリなどのインストールはItamaeを使ってインストールし、Capistranoでデプロイ出来る状態の(初期環境構築が終わった)imageを使っていきました。

データベースの情報をdockerコンテナでどう扱うかで結構悩んだのですが、毎日1回、初期環境構築が終わったimageから最新のデータを更新する用のコンテナを作成し、そのコンテナに対し本番環境から持ってきたdumpデータをリストアしてそれをimageとして保存することで対応しました。

ブランチ毎のコンテナを作成するシェルスクリプトに関しては、Capistranoでデプロイするためホスト側でマッピングされている各コンテナのsshのポート番号を取得する必要性があったのですが、

SSH_PORT=`sudo docker port ${BRANCH_NAME} 22/tcp | cut -c 9-`

みたいな感じで取得しました。対象のコンテナへのアクセスは、デプロイが終わった後にNginxで

server_name  branchname.example.com;
location @app {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass // 各コンテナ毎のhttpのport number
}

のような設定ファイルを書くことで対応しました。

使用済みコンテナの削除に関しては、最初はmasterにマージ済みのコンテナを削除するシェルスクリプトを書いたのですが、masterにマージせず放置されるブランチがあったりしたので、作成された一定期間経ったコンテナは削除する方法に変更しました。

経過時間の時刻の取得については、現在時刻とdeployした際に作成されるログファイルの作成時刻を比較して取得しています。

Dockerを使ったステージング環境を作って思うこと

完成当初のDockerのステージング環境はところどころバグがあり、発見をしては修正みたいなことを繰り返していたのですが、チームのメンバーのフィードバックを基に修正を続け、今では普通に使えるようにまでなっています。

他の人がステージングを使っているかどうか確認しなくても良いことはすごい快適で、気軽にコンテナを立ててデータベースの情報をいじれてすぐ捨てることが出来るのは結構楽しいです。

Dockerを使った各ブランチ毎のステージング環境構築、おすすめです!

以上ヤマヒロでした。

最後に

株式会社ジラフでは、CtoC新サービス「スママ」を開発するRailsエンジニアを待ち望んでます

ぜひぜひ応募、お願いします!