💭

Capistranoを使ってデプロイできたと思ったら、アセットが読み込まれてない。

2022/12/12に公開

実行環境

ruby 3.0.4
rails 6.1.7
puma/nginxを使って、
ローカルで開発したものをEC2でサーバにデプロイ
systemdを使ってデーモン化

症状

画像とCSS周りが読み込めてない。JSは読み込まめている。

capistranoタスクとしては、

deploy:assets:precompile

が実行されているはず。

原因究明

1.nginx自身の設定を確認
具体的には、/etc/nginx/nginx.confのとこです。

問題なし。
deployコマンド (起動済みのnginx)とsystectl restart puma (再起動)しても、どこにもエラーがない。アセットが反映されていないだけでアクセスもできている。

ということで
2.nginx →pumaについての設定ファイルを見てみる。
/etc/nginx/conf.d/<設定した名前>.confこのファイル
タイポや設定ミスがあるか??
→なかった

location ^~ /assets/ {
		gzip_static on;
		expires max;
    		add_header Cache-Control public;
		root /var/www/<アプリ名>/current/public/;

実際に、Capistranoを導入後に、currentディレクトリ内のpubicディレクトリを参照するように設定を直していた

3.railsアプリコードに問題がないか?
あった。

  • 以下の部分が原因でした。
# config/envrionments/production.rb

config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

この部分の意味は、Nginxやapacheに静的なファイルを配置させて、public/にあるコンパイルされたアセットファイル群をデフォルトでは、読み込まない 設定をしている部分。

対応済みだったはずの内容。

手動でデプロイさせた時に
環境変数RAILS_SERVE_STATIC_FILESに値を入れて、.present?メソッドの返り値がtrueとなるように設定してました。
(もしくはENV['RAILS_SERVE_STATIC_FILES'].present?の部分をただ、trueに書き換えても、動作する。)

原因

systemdを使った起動に問題がありました。

systemdを使った、systemctlコマンドによるデーモンとしてpumaの起動を行う際には、動作環境の環境変数は読み込まれない ようです。

そのため、本番用のEC2で立てたサーバの環境変数に指定していたRAILS_SERVE_STATIC_FILESがnilとなり、さきほどのrailsの設定ファイルが動作しなかったことが今回の原因になります。
sytemdの罠すぎる

対応

railsコードを書き換えても良いのですが、せっかくなのでsystemdに慣れるためにも、unit(systemdで設定する処理(サービス)の単位)の設定ファイルにて、環境変数を埋め込んでみることにしました。

以下のコマンドで、当該ファイルの編集をしていきます。
ファイル名は自分で設定したファイルを指定してください。

# remoteの本番環境

$ vim /etc/systemd/system/puma_<アプリ名>_production.service
# 下の方も
$ vim /etc/systemd/system/puma_<アプリ名>_production.socket

続いて、

# /etc/systemd/puma_<アプリ名>_production.socket
# もしくは、
# /etc/systemd/puma_<アプリ名>_production.socket
# を開いている状態で,

# 以下の記述を追加します。
Environment="RAILS_SERVE_STATIC_FILES=true"

参考にさせたいただいた記事)

https://bacchi.me/linux/systemd-tips/

まとめ

pumaが5.1からdaemonaizeオプション消したおかげで、systemdをつかったデーモン化を試みることになって、systemdだと、~/.bashprofile等に設定されている環境変数を読みにいかないという罠にまんまとひっかりました。

Discussion