capistranoとdocker-composeを利用してVPSにRailsをデプロイする
はじめに
大々的に広告を打ち、大手を振ってリリースするサービスであれば、最初からAWSをたっぷりと使ってみたり、GKEで大量のノードをバラ撒いてみたりと、豪勢なデプロイ環境を整えるのもアリだと思います。
しかしながら、個人が趣味で作ってみた、みたいな場合ですと、大手クラウド三社(AWS/GCP/Azure)は如何せん高すぎます。更にサービスの運用中、問題が発生して課金額が跳ね上がったとき、とても切ないことになるでしょう。
そこで活躍するのが、定額で通信量の制限もない国内のVPSでございます。メモリ4GBくらいのVPSを一台借りて、そこにアプリもデータベースも全部乗っけてしまえ、みたいなやり方、わりとよくやると思います。
ただ、こうした場合に問題となるのがコンテナの扱いです。真っ当な会社であれば、お抱えのリポジトリが社内にドーンと立っていることでしょう。しかし、趣味のサービス開発でそのようなものを維持するのは面倒です。ただでさえ会社で管理しているのに、とか。
そうなったとき、コンテナのビルドもVPS上でやってしまえ、と考えたくなるのは、貧乏な個人開発者の性ではないでしょうか。少なくとも私は考えました。ただ、手作業では絶対にやりたくありません。なにかしらデプロイツールを使うべきでしょう。
更に言えばアプリはRailsで書くのだから、Railsと親和性の高いソフトウェアがいいですね。ついでにコンテナのバージョン管理も、簡易的で構わないからVPS上で行えたら嬉しな、なんどと贅沢な私は思いを書き連ねます。
すると一つ思い浮かぶのが、そうです、枯れに枯れたデプロイツール「Capistrano」でございます。Dockerがどうのとか、Kubernetesがどうのとか、流行の話題に押しやられて、その名を耳にすることも少なくなってきた神デプロイツールです。
実装
Railsで作られたアプリケーションをDocker及びDocker Composeでコンテナ化します。Dockerfileやdocker-compose.ymlは、全てRailsのプロジェクトに突っ込みます。docker-compose.ymlについては、環境毎にproduction/stagingなどと分けると便利です。
そして、以下の通りcap taskを作成します。
Capistranoからdocker-composeコマンドを叩くことで、手元の端末からデプロイ先のVPSでコンテナをビルド、初期化、展開します。ついでにバージョンアップ時のマイグレーションや、バックアップの取得、ログの転送などもコマンドを作っておくと素敵ですね。
最後に上記コマンドを利用して、Rails Rootからデプロイを実施します。
$ bundle exec cap production deploy $ bundle exec cap production deploy:container:build $ bundle exec cap production deploy:container:init $ bundle exec cap production deploy:container:up
これにより、たった一つプロジェクトをgit cloneしてくれば、あとは端末一つVPS一台でサービスを全て管理できます。他に何も必要がないコンパクトにまとまっている感じが、個人的には気に入っております。
アプリをアップデートする際には、以下のような感じです。
$ bundle exec cap production deploy $ bundle exec cap production deploy:container:build $ bundle exec cap production deploy:container:stop $ bundle exec cap production deploy:container:migrate $ bundle exec cap production deploy:container:up
コマンドの並びが冗長だと感じる場合には、一つに纏めてしまってもいいかも知れませんね。
もちろん、docker-composeはスケールしないので、事業規模の大きなサービスには向きません。ただ、個人が趣味で作っているようなサービス、あるいは社内に閉じた小さなサービスであれば、これで十分なのではないかな、などと感じております。
Capistranoは廃らせるには惜しい神ツールです。今後とも便利に使っていきたいところでございます。