Railsアプリのデプロイまとめ【Capistrano+Unicorn+Nginx】

2022年6月15日 22:21

はじめに

当ポートフォリオサイトをVPSサーバーにデプロイしました。念願の独自ドメインも取得し、感無量という感じです。
Herokuにデプロイしていたときとは違い、様々なエラーが頻発してかなり大変な道のりではありましたが、一皮むけて成長できたと思っています。

手順は下記ページを参考にさせてもらいました。

(初心者向け)vpsを契約して、capistrano3でRailsアプリをデプロイするまで [その1 サーバー設定編]
(初心者向け)vpsを契約して、Capistrano3でRailsアプリをデプロイするまで [その2 ローカル設定編]

本記事では上記ページの手順で詰まったところを中心に書いていきます。
上記ページが間違っているというわけではなく、バージョン違いや導入済みGemの違いなど、環境差異が存在するため仕方のないことです。
誰もが本記事のようなエラーが出るとは限らないし、まったく同じエラーが出たとしても本記事の対処法がうまくいくとも限りません。
あらかじめご留意願います。

MySQL:タイムゾーンの設定

「5-4 time-zoneを設定」セクションにおいて、MySQLの設定ファイル「my.cnf」にタイムゾーンの設定を末尾に追加するという記述があります。
しかし、次の手順でMySQLコンソールにログインしようとしたところで以下のようなエラーが表示されました。
$ mysql -u root -p
mysql: unknown variable 'default-time-zone=Asia/Tokyo'
>I'm not certain what has changed in Xampp, but this solution only works if you place this line in the proper place.
symbolic-links=0                   # 既存の行
default-time-zone = 'Asia/Tokyo'   # ここに挿入
log-error=/var/log/mysqld.log      # 既存の行

Gemfile.lockによるバージョン固定

ここから先はすべて下記コマンドでデプロイを行ったときに出たエラーになります。
$ bundle exec cap production deploy --trace
「--trace」オプションを付けるとより詳細なメッセージが見れるので付けることをおすすめします。

デプロイ中に出た最初のエラーは、正確なエラーメッセージは失念してしまいましたが、bundlerのバージョンに関するエラーだったと思います。
エラーメッセージで検索するとGemfileの以下の記述を削除すればいいというページがたくさんヒットしました。
BUNDLED WITH
  2.0.2

必要なGemのインストール

これも正確なエラーメッセージは失念してしまいましたが、エラーメッセージと一緒に対処法が書かれていたのでその通り実行しました。
デプロイ対象アプリに導入済みのGemが内部で使用している別のGemがあり、それらのGemをインストールする必要があるということだと思います。
$ sudo yum install libcurl libcurl-devel
$ gem install ovirt-engine-sdk -v '4.3.0' --source 'https://rubygems.org/'

$ sudo yum -y install gcc-c++
$ gem install unf_ext -v '0.0.7.6' --source 'https://rubygems.org/'

node.jsのバージョンアップ

node.js自体は「4 node.jsのインストール」にてインストール済みですが、デプロイ中にnode.jsのバージョンに起因するエラーが出たのでバージョンアップを行いました。
$ curl --silent --location https://rpm.nodesource.com/setup_7.x | bash
$ yum -y remove nodejs
$ yum -y install nodejs
curlコマンドでnode.jsのインストール元を設定した後、インストール済みnode.jsを一旦削除し、再度インストールし直します。

bundlerのインストール

デプロイ先サーバーにbundlerをインストールします。
rbenv exec gem install bundler

環境変数 or Credentialsの設定

画像のアップロード先にAmazon S3を設定していたりActionMailの設定を行っている場合、パスワードなどの値を環境変数、またはCredentialsに設定しているかと思います。
Capistranoを使ったデプロイでは環境変数の扱いが非常に複雑なので、Credentialsに統一することをおすすめします(Rails開発チームも推奨していると思います)。
ローカルでCredentialsの設定が完了していることを前提として、デプロイ先サーバーで以下の手順を行います。

まず、Railsアプリのデプロイ先ディレクトリにmaster.keyを作成します。
$ cd /var/www/Railsアプリの名前/current/config/
$ vi master.key
# ローカルのmaster.keyと同じ内容を記述
情報元によってはcurrent/config/ディレクトリ配下ではなくshared/config/ディレクトリ配下としているところもありますが、私の場合はcurrent/config/ディレクトリ配下でうまくいきました。

次に、環境変数「.bashrc」にSECRET_KEY_BASEを追記し、再読み込みを行います。環境変数「.bash_profile」ではうまくいかないので注意してください。
$ vi ~/.bashrc
...
export SECRET_KEY_BASE=xxxxxxxxxxxxxxxxxxxxxxxxx
$ source ~/.bashrc
SECRET_KEY_BASEの値はローカルで以下のコマンドを行って確認します。
$ EDITOR=vi rails credentials:edit
...
secret_key_base: xxxxxxxxxxxxxxxxxxxxxxxxx
別の確認方法もあるようです。
参考にさせてもらったページをご覧ください。

Railsプロダクション環境のsecret_key_base取得

最後に、config/deploy.rbのシンボリックリンクを張るファイルにmaster.keyを追加します。
set :linked_files, fetch(:linked_files, []).push('config/master.key')

デプロイ完了

これにてようやくデプロイを完了することができました。
特に最後の環境変数にかかわるエラーには相当頭を悩まされ、一時は諦めることも頭をよぎりました。
Stack Overflowやteratailに質問を投げてみるも回答はつかず…
結局、独力で自己解決することになりましたが、その分デプロイがうまくいったときは本当に嬉しかったです。

関連記事

【Rails】M1チップ搭載MacでRuby on Railsの開発環境構築
# はじめに M1チップ搭載MacにRuby on Railsの開発環境を構築する手順を記載します。 - MacBook Air (M1, 2020) - macOS Monterey 12.3.1 # Homebrew ## [...]
2022年5月5日 11:56
【Rails】Rakeタスクの基本情報と作成・実行方法
# はじめに Railsには標準でRakeというGemが同梱されています。RakeはRubyで実装されたMake(UNIX系のOSで使用できるコマンド)のようなビルド作業を自動化するツールです。Ruby Make、略してRakeというわけですね。 [...]
2022年3月7日 22:12
【Rails】モデルに外部キーを設定する方法とよく起こるエラー内容について
# はじめに Railsでモデルに外部キーを設定する方法について説明します。 # モデルに外部キーを設定する ## リレーションシップ 今回は1つのブログ記事は複数のコメントを持つ1対多のリレーションシップを例に説明します。現在は` [...]
2022年2月10日 14:18
【Rails】Capybaraのfill_inメソッドを実行すると「既存レコードの内容+指定した内容」がセットされる事象の原因と対処【RSpec】
# はじめに RSpec + Capybaraを使用して、Railsアプリの統合テストを実装しています。とあるモデルの編集画面において、入力フォームの内容を書き換えた上で送信し、レコードが更新されることを確認します。 入力フォームの内容を書 [...]
2022年1月27日 21:22
【Rails】GitHubのセキュリティアラートで発見された脆弱性を解消する方法
# はじめに GitHubにはセキュリティアラートという機能があります。セキュリティアラートはリポジトリに含まれるライブラリやパッケージの脆弱性を定期的にチェックし、脆弱性のあるライブラリやパッケージが発見されたらアラートで知らせてくれるという機 [...]
2022年1月16日 10:36
【Rails】devise-two-factorを使った2段階認証の実装方法【初学者】
# はじめに Railsアプリで2段階認証を実装するには、「rotp」というGemを使う方法の他に、「devise-two-factor」というGemを使う方法があります。「devise-two-factor」はその名の通り、IDとパスワードによ [...]
2021年12月12日 17:58
【Rails】rotpを使った2段階認証の実装方法【初学者】
# はじめに 昨今はIDとパスワードによる認証だけでなく、ワンタイムパスワードによる2段階認証を導入するWebアプリが増えてきました。Railsで作成したWebアプリでも、IDとパスワードによる認証に加えて2段階認証を導入するニーズが高まっていま [...]
2021年11月27日 13:02
【Rails】deviseを使った認証機能の実装【初学者】
# はじめに Railsアプリに認証機能を導入するには「devise」というGemを使う方法が最も簡単です。「devise」は認証に係る機能をほとんどコードを書くことなく実装できる反面、処理がブラックボックス化されており、全容が把握しづらいという [...]
2021年11月27日 13:01