昨日くらいからRuby on Rails チュートリアルを始めました。

やりたいことがあっちこっちにいくことはあまり良くないなと思いつつ、モチベーションがあるうちに終わらせたいなと思ったのでコツコツやってます。

今はちょうど第3章が終わったところです。 10年くらい前に PHP でサービスを作ったことがあり勘所はあったので、今のところそこまで悩まずに進められています。

このチュートリアルの良いところは、テストを意識させてくれるところと、Heroku を使った本番環境へのデプロイがあるところですね。実践的な開発を意識して勉強できることはとてもいいですね。

さて、ここでもう一歩踏み込んだことをしてみたいと思います

手元でテストして Heroku にデプロイするのって面倒くさいですよね?1ってことで、タイトルにある通り、この手順を自動化したいと思います。

チュートリアルだとBitbucketを使ってますが、僕はGitLabを使っています。どのホスティングサービスを使うかは好みなのでGitHubでもいいと思いますが、GitLabは CI/CD が統合されてるので便利かと思います。GitHubを使う場合はCircleCIなどほかの CI サービスと連携すれば同じことができます。

最終的には、GitLabmasterブランチに push したときに、自動テストしてパスしたら Heroku にデプロイできるようにします。

自動でテストを動かす

どこでミスをしたかわかりやすいように、段階を踏んで少しずつ設定をしていきます。

まず GitLabmasterブランチに push したときに、自動テストを行うようにします。

.gitlab-ci.yml というファイルをリポジトリ直下に置くと、push したときにこの設定を読んで色々してくれます。

test:
  stage: test
  script:
  - apt-get update -qy
  - apt-get install -y nodejs
  - gem install rails -v 5.1.4
  - bundle install
  - rails db:migrate RAILS_ENV=test
  - rails test

ただコマンドを羅列しているだけなので、見てもらえればすぐ理解できると思います。注意するところは開発環境と同じバージョンの Rails をインストールするところでしょうか。

rails testが失敗したら通知が届いて、次のデプロイに進みません。エラーが出る場合はログを見て修正しましょう。

Heroku にデプロイする

テストがすべて成功したらHerokuにデプロイできるようにしましょう。ここではdplというコマンドラインツールを使ってデプロイします。

production:
  stage: deploy
  script:
  - gem install dpl
  - dpl --provider=heroku --app=pacific-earth-65195 --api-key=$HEROKU_PRODUCTION_API_KEY

dplコマンドの--appオプションで指定されてる名前は自身のアプリ名を指定してください。

HEROKU_PRODUCTION_API_KEYは環境変数で、GitLabに設定します。もしパブリックリポジトリで.gitlab-ci.ymlファイルにAPIキーを直接書いてしまうと、そのキーを使って誰でもHerokuにアクセスできてしまうので、セキュリティの観点から危険です。 APIキーは絶対に直接書かずに環境変数などで指定するようにして、誰でも見えるようにしないでください。

SettingCI/CDを順にクリックして、VariablesExpandをクリックすると環境変数を設定できるようになります。上の画像みたいになるはずです。

ここに入力するAPIキーは、Herokuアカウント管理画面に書いてあるAPIキーを使います。

全体像

最終的の.gitlab-ci.ymlは以下のようになります。

testdeployの2ステージのパイプラインになっていて、testが成功するとdeployが実行されるようになります。

stages:
 - test
 - deploy

test:
  stage: test
  script:
  - apt-get update -qy
  - apt-get install -y nodejs
  - gem install rails -v 5.1.4
  - bundle install
  - rails db:create RAILS_ENV=test
  - rails test
  
production:
  stage: deploy
  script:
  - gem install dpl
  - dpl --provider=heroku --app=pacific-earth-65195 --api-key=$HEROKU_PRODUCTION_API_KEY

rails db:migrate を誰がやるのか

Ruby on Rails チュートリアルを進めていくと、rails db:migrateコマンドを実行することがあります。しかし、上記の設定だとそこまでやりません。

データベースのマイグレーションなので、GitLabrails db:migrateをしても意味がありません。デプロイ先はHerokuなので、そこで行う必要があります。

そこでRelease Phase機能2を使います。詳しくは公式ドキュメントを見てほしいのですが、デプロイ後に

  • CDN にCSS/JSを送る
  • キャッシュを無効化する
  • データベースのマイグレーションをする

などを行うための機能です。

Procfileを使うとHerokuにいろいろ指示・設定ができます3Procfileはルートディレクトリに置く必要があります。

次のように設定するとデプロイした後にrails db:migrateを行って、それが終わるとデプロイしたバージョンにアクセスできるようになります。

release: rails db:migrate

最後に

これでmasterpushするとテストしてHerokuにデプロイできるようになりました。少しモダンな環境になりました。

ただ毎回gem insallを実行するので時間がかかります。 Dockerであらかじめテスト環境を構築しておけばもう少し早くなるのかな…?と思ったりします。 GitLab上での使い方が分からないのでまた違う機会で調べてみたいと思います。

分からないことがあれば、@takuchalleにリプライでもDMでも聞いてください。


  1. もちろん手元でテストをしないで良いということではないです。人間は忘れやすい生き物ですので、自動化して機械にもチェックしてもらおうってことです。
  2. Release機能の公式ドキュメントはこちら
  3. 7章で Puma を使うときにも Procfile を使いますね