概要
個人開発しているサービスを Heroku で運用していたのだが、無料プランが 2022/11/28 (だいぶ前)に終了したのもあり、いつか別の環境に変更しようと思っていた。
Heroku の代替サービスとなるものは色々な記事でまとめられているが、個人的に Dokku (オープンソースで提供されている PaaS) がよさそうだったので、今回は VPS + Dokku 環境にデプロイしてみた。
Dokku 自体は無料で利用できるので、VPS のレンタル先次第で Heroku より安く運用できる。
自分は Heroku で Redis も使用していた関係で $8/月 かかっていたが、今回は ConoHa で VPS をレンタルして Heroku より安く済んだ。
(1年プランにしたのもあって、月500円くらいになった)
記事執筆時の環境
Ruby on Rails: 6.1.4.4
Dokku: 0.30.3
手順
VPS の契約
Dokku は Ubuntu か Debian 上にインストールする必要がある1 ため、それらが使える環境を用意する。
今回は料金が安かったので、ConoHa の VPS をレンタルしてみた。
Dokku のドキュメントによると、メモリは1GB以上必要2 なので以下を選択した。
※以下は記事執筆時点の料金なので自分が契約したときよりちょっと高くなっていた。
https://www.conoha.jp/vps/?btn_id=top--commonHeader_vps-top
OS は Ubuntu の 22.04 (64bit) を選択した。
サーバー作成時のオプションで SSHキーの作成、登録も同時にできるので、ここであわせてやっておくと楽だった。
Dokku のインストール
VPS が用意できたら、Dokku のドキュメントに従いインストールする。
https://dokku.com/docs/getting-started/installation/#installing-the-latest-stable-version
wget https://dokku.com/install/v0.30.3/bootstrap.sh sudo DOKKU_TAG=v0.30.3 bash bootstrap.sh
上記の実行に10分くらいかかった。
完了後、SSHキーを登録する。
cat ~/.ssh/authorized_keys | dokku ssh-keys:add admin
グローバルドメインの設定 (dokku domains:set-global
) では IP アドレスを指定することも可能らしいが、今回はお名前.comで独自ドメイン (この記事内では example.com
と呼ぶことにする) を取得してみたので、それを使う。
dokku domains:set-global example.com
Rails アプリケーションのデプロイ
これも基本的に Dokku のドキュメントに従えばよい。
https://dokku.com/docs/deployment/application-deployment/
ローカル環境で、デプロイしたいリポジトリをクローンする。
git clone https://github.com/[your_user_name]/[your_repository_name]
今度は SSH 接続したサーバー上でアプリの登録をする。(今回は rails-sample-app
という名前で進めます)
dokku apps:create rails-sample-app
次に DB のインストールをする必要があるが、PostgreSQL を使っているならドキュメントのとおり進めればいけるはず。
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git dokku postgres:create railsdatabase dokku postgres:link railsdatabase rails-sample-app
もし MySQL を使っているなら、上記の代わりに以下のようにする。
sudo dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql dokku mysql:create railsdatabase dokku mysql:link railsdatabase rails-sample-app
再度、ローカル環境に戻り、クローンしたリポジトリのディレクトリで以下を実行する。
git remote add dokku dokku@example.com:rails-sample-app git push dokku main:master
git push
時に DB 未作成によるエラーが出るようであれば、ローカルで以下を実行後に再度 git push
する。
※ ローカルで dokku
コマンドを使うには、dokku-cli
3 をインストールしておく必要がある。
dokku run rails db:create dokku run rails db:migrate
Dokku のドキュメントだと、これで http://rails-sample-app.example.com
に接続できるようになっているが、自分の場合は以下を実行してからでないと接続できなかった。(単に自分がドキュメントに記載された手順を間違えていたり、すっ飛ばしていただけかもしれない)
dokku domains:set rails-sample-app rails-sample-app.example.com
※ この後に再デプロイ (dokku ps:rebuild rails-sample-app
) が必要だったかもしれない。
以上で、http://rails-sample-app.example.com
に接続でき、Rails アプリケーションを動作するための最低限の対応が完了。
+α
SSL 化
このままだと http 接続しかできないため、これも Dokku のドキュメントに従えば容易に SSL 化できる。
https://dokku.com/docs/deployment/application-deployment/#setting-up-ssl
dokku certs:add rails-sample-app server.crt server.key sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git dokku letsencrypt:set --global email your-email@your.domain.com dokku domains:set rails-sample-app rails-sample-app.example.com dokku letsencrypt:enable rails-sample-app dokku letsencrypt:cron-job --add
これで、https://rails-sample-app.example.com
に接続できるようになる。
Redis の設定
もし Sidekiq で非同期処理をして Redis を使っていたら、これも Dokku の公式プラグインを利用すれば容易に対応できる。
https://github.com/dokku/dokku-redis#installation
sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis dokku redis:create rails-sample-app_redis dokku redis:link rails-sample-app_redis rails-sample-app # 再デプロイが必要かも dokku ps:rebuild rails-sample-app # Procfile を用意していると思うので、これもデプロイ後に必要(毎回やる必要はないはず) dokku ps:scale rails-sample-app web=1 worker=1
Cron の設定
定期実行処理をしている場合もドキュメントに従えば容易に Cron を設定できる。
https://dokku.com/docs/processes/scheduled-cron-tasks
リポジトリのルートディレクトリに、以下のような内容で app.json
を用意し、dokku に push するとあとは勝手に設定されている。
e.g.
{ "cron": [ { "command": "rails hoge_batch", "schedule": "@daily" } ] }
dokku cron:list rails-sample-app ID Schedule Command [ハッシュ値] 0 * * * * rails hoge_batch
Chrome, ChromeDriver のインストール
自分が作成している個人サービスではクローリングもできるようにしているため、Chrome と ChromeDriver も欲しかった。
これについてはネット上の記事が少なく、どうしたら実現できるかわからなかったのだが、ドキュメントを読み込んでいたら herokuish-buildpacks
というのが用意されており、Heroku でも使っていた Buildpack がそのまま使えることがわかった。(めちゃくちゃありがたい)
なので、ドキュメントのコマンド例を参考に、以下を実行すればインストールできた。
https://dokku.com/docs/deployment/builders/herokuish-buildpacks
Buildpack を追加する。
# Chrome dokku buildpacks:add rails-sample-app https://github.com/heroku/heroku-buildpack-google-chrome.git # ChromeDriver dokku buildpacks:add rails-sample-app https://github.com/heroku/heroku-buildpack-chromedriver.git # Ruby dokku buildpacks:add rails-sample-app https://github.com/heroku/heroku-buildpack-ruby.git
※ Chrome と ChromeDriver 用の Buildpack を追加すると、ビルド時に Ruby のバージョンが古くなってしまい bundle install
でエラーになる可能性があるため、最後に Ruby の Buildpack も追加する。
あとは、インストールした Chrome の同等バージョンを CHROMEDRIVER_VERSION
に設定しておく。
dokku config:set CHROMEDRIVER_VERSION=[Chromeと同等のバージョン]
GitHub Actions で自動デプロイ
今後も修正したコードを Dokku 環境に適用したいときは、毎度 git push dokku main:master
をしないといけないため、せっかくならと思い、GitHub Actions で自動デプロイも設定してみた。
とてもありがたいことに、こちらもドキュメントが用意されており、ほぼそのまま使えた。
https://dokku.com/docs/deployment/continuous-integration/github-actions
まず、GitHub の該当リポジトリの secrets に好きな名前 (今回はサンプルと同じく SSH_PRIVATE_KEY
) で ConoHa の VPS に接続するときの鍵情報を登録する。
https://github.com/[your_user_name]/[your_repository_name]/settings/secrets/actions/new
あとは、該当リポジトリに .github/workflows/deploy-to-dokku.yml
とかという名前で以下の内容のファイルを作成し、main ブランチにマージすると自動デプロイができるようになる。
--- name: 'deploy' on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Cloning repo uses: actions/checkout@v3 with: fetch-depth: 0 - name: Push to dokku uses: dokku/github-action@master with: git_remote_url: 'ssh://dokku@example.com:22/rails-sample-app' ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
所感
Dokku はとにかく便利だった。
日本語の関連記事が少なかったのと、Heroku と違って自分で VPS を用意して CLI で構築していかなければいけなかったので、そこらへんはいろいろと勉強になってよかった。