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

開発サーバで複数バージョンのアプリケーションを動作させるための施策

  • プルリクをマージする前に開発サーバで動作確認したい
  • 本番にデプロイする前に開発サーバで動作確認したい

といったニーズを満たすために行った施策を紹介する。

前提の説明

GitHub Flowで複数人の開発者が開発している。 upstreamのリポジトリを各人がForkし、チケットごとにブランチを切り、upstream/masterにプルリクを投げる。 レビューしてOKだったらマージする。というフローを取っている。

実現すること

開発者fooのhogehogeブランチを開発サーバで動作確認したい場合、 開発サーバにそれをデプロイし、

http://hogehoge.foo.(開発サーバのドメイン)

のようにURLを割り当てるようにする。 タグやリビジョン番号で同様に

http://(タグ名・リビジョン番号).(開発サーバのドメイン)

みたいにURLを割り当ててもよいかもしれないが、今の所それはやっていない。

使用した主なツールなど

  • Docker Engine - 複数のアプリケーションをコンテナとして動かす
    • nginx-proxy - サブドメインによってリクエストを各コンテナに割り振る
  • Fabric - デプロイサーバから開発サーバにデプロイする

構成の概要図

draw.ioで図にしてみた。

f:id:kics:20160715011728p:plain

デプロイ時に具体的にやること

$ ssh デプロイサーバ  # 開発者がデプロイサーバにSSHログイン
$ su deployer  # デプロイ用のユーザになる。これは本当にこれで良いのか
$ cd デプロイスクリプトがあるディレクトリ  # fabコマンドを実行するために移動
$ fab --set repo=foo/hoge build deploy  # デプロイ対象を指定してビルド・デプロイ

詳細

自分はアプリケーションを動かす場合基本的にDockerコンテナ上で動かすようにしている。 複数のアプリケーションを動かす場合、各アプリケーションの依存ライブラリ及びそのバージョンとかが異なったりするが、 各アプリケーションをコンテナとして動かせば困らない。 いらなくなったらコンテナごと削除すればよいので楽。

各コンテナにサブドメインを割り振るのだが、これは

github.com

を使えば簡単。

Dockerを使ったデプロイではソースコードをイメージに含めてビルドし、デプロイのたびにコンテナ作り直すようにすることも出来るが、 毎回イメージをビルド、pullするのは辛いので、ソースコードをホストにデプロイし、コンテナにマウントするようにしている。 依存ライブラリもデプロイ時にインストールしているのだが、完全に1からインストールすると時間がかかってとても効率が悪いので 少し前のリビジョンの依存ライブラリをインストール済みのDockerイメージを使用し、それに足りないものだけを毎回インストールするようにしている。 このイメージは必要に応じて更新する。 GitHubとDocker Hubを連携してプルリクやマージのたびにイメージを自動でビルドするようにし、それを使うのもありかもしれない。

(余談だが、依存ライブラリのインストールをイメージに含めてしまわないのはDockerの使い方としてどうなのかという意見もあるかもしれないが、 ビルドやpullのコストを考えると、現実的にはありだと自分は思っている。)

ソースコードCSSやJSをビルドする必要があるが、それは開発サーバで行うのではなく、デプロイサーバ上で行い、 ビルドしたものをFabricのrsync_projectで転送するようにしている。 そうすれば開発サーバにNode.jsとかいらない。

デプロイは各開発者がデプロイサーバにSSHログインし、Fabricでデプロイするようにしている。この辺は

複数プロジェクトを抱えるチームでのデプロイ自動化 | SOTA

を参考にしている。

タスクとして以下のようなものを作成している。

  • build # git pull(clone), CSS/JSなどのビルド
  • deploy # デプロイ
  • destroy # コンテナやDBスキーマを削除
  • stop # コンテナの停止
  • restart # アプリケーションの再起動

最後に

以上のような方法で今の所うまく行っている。 ただ、本当にこれで良いのか、もっとうまい方法がないかと言うと、分からない。

今回の施策を打つのには結構な工数をかけていて、 GAEみたいなPaaSなんかだと自分がやったことはうまいこと勝手にやってくれたりするらしい(そんなこと聞いた気がする)ので、 そういう点ではPaaSは便利だなと思う。

qiita.com An Overview of App Engine  |  App Engine standard environment for Python  |  Google Cloud Platform