概要
Railsの本番環境を作る手順です。
環境
- Ubuntu20.4 (vagrant)
- PostgreSQL12.4
- Rails5.2
手順
アセットファイルのプリコンパイル
アセットファイルをプリコンパイルします。JavaScriptsでコードを書いている場合、プリコンパイルでYarnが使われます。Yarnがインストールされていなければ、Yarnがありませんというエラーメッセージが表示されますので、事前に、Yarnをインストールしておく必要があります。
$rails assets:precompile RAILS_ENV=production
(トラブルシュート)
このようなエラーが出てきました。対応方法はメッセージにある通りです。ハーモニックモードを有効にする設定場所は、config/production.rbです。To use ES6 syntax, harmony mode must be enabled with Uglifier.new(:harmony => true). (訳)ES6 構文を使用するには、Uglifier.new(:harmony => true) でハーモニー モードを有効にする必要があります。
アセットファイルを削除するときのコマンドです。public/assetsのディレクトリが削除されます。
$rails assets:clobber
database.ymlの編集
database.ymlのproduction項目を本番用に編集します。ここで重要なのはusernameとpasswordです。本番環境なので、セキュリティを上げるために、database.ymlに直接記述するのではなく、環境変数に記述する方がいいでしょう。
環境変数を設定するために、Railsにはdotenvというgemが使われることが多いようです。dotenvを利用する場合は、.envファイルに環境変数を記述します。production環境でも、development環境と同じusername、passwordを指定することはできますが、変えた方がセキュリティ的にはいいでしょう。database.ymlで設定するusernameとpasswordは、OSにログインするときの認証情報ではなく、PostgreSQLにログインするときの認証情報です。
PostgreSQLでロールを作成
PostgreSQLに本番用のログイン認証を行うロールを作成します。development環境とproduction環境とで、同じユーザーでログインするのであれば、改めてロールを作成する必要はありませんが、それぞれ異なるロールでログインするのであれば、production用に新規でロールを作成する必要があります。
ロールを作成するとき、オプションでパスワードを指定することを忘れないでください。指定し忘れても、alter roleでパスワードを後から設定することはできます。また、drop roleして、再度、create roleしてもどちらでもOKです。
ロールにはSuperuserの権限を付与してください。Superuserだけでいいです。(注:状況に応じてにはなります)権限の付与は、alter roleで行えます。SuperuserでないとRailsの起動時にエラーになりました。
PostgreSQLへのログインはデフォルトでpeer認証で認証されるようになっています。peer認証で認証させるのであれば、OS側にもロールと同じ名前のユーザーを作成しておく必要があります。パスワードまでは同じにしておく必要はありません。
パスワード認証にするのであれば、OS側にロールと同じ名前のユーザーを追加する必要はありません。その代わり、pg_hba.confに追加したロールの認証設定を1行追加してパスワード認証を有効にする必要があります。
データベースを作成する
本番用のデータベースを作成します。
$rails db:create RAILS_ENV=production
PostgreSQLにログインして、本番用のデータベースが作成されていることを確認します。postgresユーザーでログインしても、本番用のロールでログインしても、同じように表示されます。本番用のロールでログインした後、テーブル一覧を表示させると、当然、この時点では何のテーブルも表示されていません。
$sudo su postgres
$psql -d プロジェクト_production
#\l
$psql -U ロール名 -d データベース名
#\l
#\dt
テーブルを作成する
つぎのコマンドを実行すると、テーブルがありませんといったメッセージが表示されます。マイグレーションの一覧が、すべてdownされた状態で表示されるわけではありません。
$rails db:migrate:status RAILS_ENV=production
マイグレーションファイルを本番用に流します。エラーなくすべてのマイグレーションファイルが流れてくれるか、少し緊張する瞬間です。正常に流れてくれれば、その後、ステータスを表示すると、マイグレーションの一覧が、すべてupされた状態で表示されます。
$rails db:migrate RAILS_ENV=production
$rails db:migrate:status RAILS_ENV=production
初期データを更新
seeds.rbに初期データを更新する処理を記述して、初期データが更新します。
$rails db:seed RAILS_ENV=production
初期データの更新確認
PostgreSQLに本番用のロールでログインして、初期データが更新されていることを確認します。seedsを流していないテーブルは当然、データは入っていないはずです。「あれ?データが入っている!」となれば、誤ってdevelopment環境のデータベースに接続してしまっています。
$sudo su - postgres
$psql -d プロジェクト名_production
#\dt
#select * from users;
#select * from テーブル;
Railsの起動確認
本番環境でRailsが起動されることを確認します。ちなみに「rails s RAILS_ENV=production」では動作しません。
#rails s --environment=production
ログ管理
Railsで開発をしていれば、log/development.logは次々と更新されていくことになります。デフォルトではログローテートがされるようになっておらず、開発を続けていくと、ログは際限なく肥大化していくことになります。気が付けばギガ単位にまで膨れ上がっていたなんていったこともあります。
本番環境では、デフォルトのままではログが作成されるようになっていません。もう少し詳しくいえば、ログは作成されるようになっているが、デフォルトの設定で有効になっていないということです。ログを有効にするには、次の環境変数を設定します。
RAILS_LOG_TO_STDOUT = true
この環境変数を設定すればログが作成されるようになるが、ログローテまでは行ってくれるようにはなりません。別途、設定をする必要があります。
ログローテはOSに標準で用意されているcronを使って行うこともできるが、Rails側で行うこともできます。Rails側で行うにはLoggerクラスを使います。
例えば、つぎの設定はこのような意味になります。
- ログファイルの容量が10MBに達したら、つぎの新しいログファイルが作成されいます。
- ログのバックアップファイルの履歴は5個まで保持します。
- 6個目のログが作成されるタイミングで、一番古いバックアップファイルが削除されます。
config.logger = Logger.new("log/production.log", 5, 10 * 1024 * 1024)
参考
https://takeda-no-nao.net/programming/ruby/delete-log-files-after-certain-period-of-time/
その他
開発で作成されたログ、キャッシュファイルもクリアしておきましょう。
#rails tmp:clear
#rails log:clear