はじめに
AWS上にCapistranoを使用してRailsアプリをデプロイしましたが、ブラウザー上に「We're sorry, but something went wrong.」と表示されてしまうエラーに遭遇して、エラーの解決に苦戦しましたため、同様の悩みをお持ちの方のお役に立てばと思い、記載いたします。
開発環境
- Mac
- Ruby 2.7.2
- Rails 6.1.3.1
- PostgreSQL 13.2
本番環境
- puma
- nginx
- AWS(EC2、RDS、VPC、S3)
前提
RailsアプリをHerokuとS3を使用した環境で上手くデプロイできましたため、AWS(EC2、RDS、VPC)環境にRailsアプリをデプロイした際に発生したエラーとなります。
エラーの事象
ローカル環境のターミナルで「bundle exec cap production deploy」コマンドを実行し、表示されたIPアドレスをブラウザーに入力後、以下の画面が表示されました。本来であれば、アプリケーションのトップページが表示されるはずですが、エラー画面が表示されてしまいました。
ローカル環境のターミナルでデプロイエラーは出ていなかったため、サーバー環境のターミナルで「/var/www/アプリケーション名/shared/log/nginx.error.log」を確認したところ、以下のメッセージが表示されました。
2021/10/04 08:00:08 [crit] 25745#25745: *539 connect() to unix:/var/www/stop_sweets/shared/tmp/sockets/puma.sock failed (2: No such file or directory) while connecting to upstream, client: xx.xx.xx.xxx, server: localhost, request: "GET /blog/wp-includes/wlwmanifest.xml HTTP/1.1", upstream: "http://unix:/var/www/stop_sweets/shared/tmp/sockets/puma.sock:/blog/wp-includes/wlwmanifest.xml", host: "xx.xx.xx.xxx"
2021/10/04 08:00:09 [crit] 25745#25745: *539 connect() to unix:/var/www/stop_sweets/shared/tmp/sockets/puma.sock failed (2: No such file or directory) while connecting to upstream, client: xx.xx.xx.xxx, server: localhost, request: "GET /web/wp-includes/wlwmanifest.xml HTTP/1.1", upstream: "http://unix:/var/www/stop_sweets/shared/tmp/sockets/puma.sock:/web/wp-includes/wlwmanifest.xml", host: "xx.xx.xx.xxx"
「sockets/puma.sock failed (2: No such file or directory)」というメッセージでググってみたところ、pumaが起動した際にpuma.sockというファイルが作成されるとのことですので、pumaが上手く起動していないことによるエラーなのではと思い、pumaが上手く動かない原因を調べてみました。
以下のpuma起動用スクリプトからpumaを起動しているコマンドを確認しました。
[Unit]
Description=Puma HTTP Server for stop_sweets (production)
After=network.target
[Service]
Type=simple
User=stop_sweets_user
WorkingDirectory=/var/www/stop_sweets/current
ExecStart=/home/stop_sweets_user/.rbenv/bin/rbenv exec bundle exec puma -C /var/www/stop_sweets/shared/puma.rb
ExecReload=/bin/kill -TSTP $MAINPID
StandardOutput=append:/var/www/stop_sweets/shared/log/puma_access.log
StandardError=append:/var/www/stop_sweets/shared/log/puma_error.log
Restart=always
RestartSec=1
SyslogIdentifier=puma
[Install]
WantedBy=multi-user.target
上記のpuma起動用スクリプトから確認した起動コマンド「bundle exec puma -C /var/www/アプリ名/shared/puma.rb」をサーバー環境ターミナルのディレクトリ「/var/www/アプリ名/current」で実行したところ、以下のログが表示されました。
Puma starting in single mode...
* Puma version: 5.2.2 (ruby 2.7.2-p137) ("Fettisdagsbulle")
* Min threads: 0
* Max threads: 16
* Environment: production
* PID: 13673
! Unable to load application: ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_key
bundler: failed to load command: puma (/var/www/stop_sweets/shared/bundle/ruby/2.7.0/bin/puma)
Traceback (most recent call last):
57: from /home/stop_sweets_user/.rbenv/versions/2.7.2/bin/bundle:23:in `<main>'
56: from /home/stop_sweets_user/.rbenv/versions/2.7.2/bin/bundle:23:in `load'
エラーメッセージ「ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_key」でググってみたところ、Railsアプリ内で画像投稿用のgem「CarrierWave」を使用して、投稿した画像をS3に保存するようにしておりましたが、S3を使用するためのアクセスキーとシークレットキーを設定していなかったことによるエラーであることが分かりました。そのため、railsアプリ内のコードを以下のように修正しました。
if Rails.env.production?
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
aws_secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key),
region: Rails.application.credentials.dig(:aws, :region)
}
config.fog_directory = Rails.application.credentials.dig(:aws, :bucket)
end
end
aws:
access_key_id: 【IAMユーザーのアクセスキーID】
secret_access_key: 【IAMユーザーのシークレットアクセスキー】
region: ap-northeast-1
bucket: 【S3のバケット名】
上記の修正後、githubのmainブランチに反映し、ローカル環境のターミナルで「bundle exec cap production deploy」コマンドを実行致しました。ブラウザーからアプリへアクセスしたところ、無事にトップページが表示されるようになりました。
まとめ
- デプロイログやサーバログに真因に関するメッセージが出ていなかったため、 解決に手こずりましたが、エラーメッセージから地道に調査していくことが大切だと思いました。
- nginxやpumaなどのサーバに関する知識も必要だと思いました。サーバに関する知識がないと原因がアプリ側なのか、インフラ側なのかの原因の切り分けが難しいと思いました。