ミナミ(@minami_nakasato)です。
プログラミングスクールの課題でメル○カリのコピーアプリを制作しています。
その際Capistranoを使った自動デプロイに取り組んだのですが、どうにもエラーが止まらず難儀しました。
「どんなハイレベルな原因なのか」と悶えるも、冗談みたいに初歩的なミスだった話です。
作業環境
■Ruby 2.5.1
■Ruby on Rails 5.2.4
■本番環境
AWS(EC2)内に
webサーバー:nginx
アプリサーバー:Unicorn
データベース:MySQL
経緯
①「Rails new」コマンドでアプリを立ち上げる
②いったんCapistarnoの自動デプロイに成功。
③テーブルを用意するため「Rails g model」コマンドを実行。
生成されたのは以下のファイル
(1)モデルファイル
バリデーションとアソシエーションを記入。
(2)マイグレーションファイル
カラム名/データ型/not null制約
などなどを記入。
④「rails db:migrate」でテーブルを作成。
⑤ローカル環境で正常に動作する事を確認。
⑥自動デプロイのために「bundle exec cap production deploy」コマンドを実行。
すると、以下のエラーが表示される。
00:13 unicorn:start
01 $HOME/.rbenv/bin/rbenv exec bundle exec unicorn -c /var/www/frima/current/config/unicorn.rb -E deployment -D
01 master failed to start, check stderr log for details
#<Thread:0x00007fc1a0e12be8@/Users/lowgetsudo/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /Users/lowgetsudo/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/lowgetsudo/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.20.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing as ec2-user@3.115.193.237: bundle exit status: 1 (SSHKit::Runner::ExecuteError)
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@3.115.193.237: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
Caused by:
SSHKit::Command::Failed: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
Tasks: TOP => unicorn:start
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as ec2-user@3.115.193.237: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
** DEPLOY FAILED
対応その1
「途中までは順調だったが、本番環境のunicornを起動する段階(unicorn:startのところ)でエラーになっておるな」
「nginxを手動で再起動しよう」
本番環境の当該アプリディレクトリで
$ sudo service nginx restart
「unicornを手動で再起動しよう」
本番環境の当該アプリディレクトリで
$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
ふたたび自動デプロイコマンドを実行!
…失敗。
対応その2
「おれは先ほどローカルでテーブルを作る処理を行った」
「その後にエラーが起きたという事は、データベースに関係するエラーじゃろか」
「本番環境のデータベースを一度リセットしてみよう」
…以下のコマンドを順番に実行↓
①「git pull origin master」コマンドでGitHubのリモートリポジトリの中身をEC2に入れ込む。
②本番環境のDBを破壊
$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rails db:drop
③本番環境にDBを構築
$ rails db:create RAILS_ENV=production
④本番環境にテーブルを生成
$ rails db:migrate RAILS_ENV=production
上記を実行後、再び自動デプロイのコマンドを実行!
…しかし、同じエラーがまだ続く。
対応その3
「そもそも、まずはエラーログを読むべきなんじゃないのか」
(ここでようやく気付く)
EC2に入り、ログを確認。
I, [日付と時間 #10169] INFO -- : Refreshing Gem list
bundler: failed to load command: unicorn (/var/www/frima/shared/bundle/ruby/2.5.0/bin/unicorn)
NameError: undefined local variable or method `belongs_to ' for #<Class:0x0000000004ddc5d0>
Did you mean? belongs_to
という文言が表示される。
NameErrorの中身を訳すと、
『"belongs_to " なんて変数やメソッドはありませんよ』
『"belongs_to" の間違いじゃないのかね?』
「どういうこっちゃ!」
「”belongs_to”という文言、ということはモデルファイル内の記述ミスか」
「よく見ると、どうやらbelongs_toの後の
" " (スペース)
に問題があるようだ」
確認してみると、
普通の半角スペースに見えるが、一応すべてスペースを削除&再び追記してみる↓
すると、自動デプロイ成功!
原因
画像をよく見比べると、
訂正前はただの半角スペース
訂正後は白い「・」がついた半角スペース
となっている。
エラーの原因になったモデルを記入する際に、別のモデルファイルからコピー&ペーストしたが、その際に今回の「よくない半角スペース」になってしまったらしい。
そういえば前にも
半角の「" "」をコピペしたところ、
貼り付けると
全角の「” ”」になってしまいエラーが出たことがあった。
コピペはこういうエラーの原因になりがちなようだ。
よく確認しよう!
======================================
ミナミ(@minami_nakasato)です。都内のベンチャー企業でwebデザイン/プログラミング/動画撮影や編集などをやっています。