『Ruby on Rails Advent Calendar 2022』24日目の記事です。
はじめに
スタートアップでエンジニアリングマネージャーやったりスクラムマスターやったりしている人です。
今回は、「rails server
コマンド打った時、Pumaはどこの設定を読み込んでいるのか?」について調べたので、備忘録として記事にしました。
rails server
コマンド自体の仕組みを解説している記事はそこそこヒットするんですが、意外とrails server
した時のPumaの設定ってどこに書いてあるの?という記事はなかった気がするので、書いてみることにしました。
対象読者は、Rails初学者 〜 経験1・2年くらいの、「Rails開発に少し慣れてきて、動くコードはそれなりに書けるようになってきた気がするけど、内部の仕組みについても少しずつ理解を深めていきたいよ〜」くらいの方がターゲットとなっています。
(時間がない方のために)結論
時間がない忙しいあなたのために、まず結論をお伝えします。
Pumaのソースコード(puma/lib/puma/configration.rb)のpuma_default_options
というメソッドにデフォルト設定が書いてあり、Railsアプリにconfig/puma.rb
やconfig/puma/<environment_name>.rb
があるとそれが読み込まれ、デフォルト設定をオーバーライドします。
調べることになったきっかけ
会社のプロダクトはCapistranoでデプロイ行っています。capistrano-puma
gemのバージョンを上げるついでに、Pumaの設定ファイルを Capistranoデフォルトであるサーバー上の{app_root}/shared/puma.rb
から、Railsアプリの config/puma/<environment_name>.rb
を読み込むように変更しました。
この変更の過程で、開発環境でrails server
コマンドを叩いた時に、config/puma.rb
ファイルがないのにPumaが起動できてしまいました(Railsのデフォルトで config/puma.rb
は存在しますが、ファイルリネームされてその時は存在しなかった)。
Puma起動時に 、config/puma.rb
やconfig/puma/<environment_name>.rb
を見に行くことはCapistranoの設定変更で知っていましたが、どちらも存在しないのに起動できたのが不思議でした。
というわけで、「おそらく設定ファイルがなくてもどっかにデフォルトの設定があって、初期値として設定されているんだろう」の仮説のもと、それがどこに書かれているのかを探しにいくことにしました。
Pumaのソースコードに書いてあった
結論、Pumaのソースコードに書いてあったのですが、どうやって見つけたかの過程を残しておきます(他にいい方法あれば教えていただきたい)。
rails new
したときに作られるconfig/puma.rb
に書いてある設定のうち、とりあえずworker_timeout
あたりでRubyMineを使って全検索してみる。
Scopeを「All Place」にすると、プロジェクトのソースコードだけでなく、インストールしたGemのソースコードまで検索対象に含めてくれます。
あった!!!
該当のソースコードはこちら
# puma/lib/puma/configration.rb def puma_default_options { :min_threads => 0, :max_threads => 16, :log_requests => false, :debug => false, :binds => ["tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"], :workers => 0, :daemon => false, :mode => :http, :worker_timeout => DefaultWorkerTimeout, :worker_boot_timeout => DefaultWorkerTimeout, :worker_shutdown_timeout => DefaultWorkerShutdownTimeout, :remote_address => :socket, :tag => method(:infer_tag), :environment => -> { ENV['RACK_ENV'] || "development" }, :rackup => DefaultRackup, :logger => STDOUT, :persistent_timeout => Const::PERSISTENT_TIMEOUT, :first_data_timeout => Const::FIRST_DATA_TIMEOUT, :raise_exception_on_sigterm => true } end
puma_default_options
というメソッド内で、他にもいろいろ定義されているっぽい!
PumaのREADME
さらに、PumaのREADMEを見ると、Configuration File
のブロックで以下のように書いてありました。
If no configuration file is specified, Puma will look for a configuration file at config/puma.rb. If an environment is specified (via the --environment flag or through the APP_ENV, RACK_ENV, or RAILS_ENV environment variables) Puma looks for a configuration file at config/puma/<environment_name>.rb and then falls back to config/puma.rb.
(訳) 設定ファイルが指定されていない場合、Puma は config/puma.rb にある設定ファイルを探します。環境が指定された場合 (--environment フラグまたは APP_ENV、RACK_ENV、RAILS_ENV 環境変数を使用) Puma は config/puma/<environment_name>.rb から設定ファイルを探し、その後 config/puma.rb にフォールバックします。
要するに、puma_default_options
で定義されたデフォルト設定があり、config/puma.rb
やconfig/puma/<environment_name>.rb
があった場合、読み込んでデフォルト設定をオーバーライドしてくれるんですね〜〜
だから、設定ファイルがなくてもデフォルト設定で動かすことができたんですね!(解決!)
おわりに
Railsにある程度の年数触れてきた方にとっては特に目新しさのない内容だったかとは思います。
しかし、個人的にはCapistranoの設定変更に始まり本記事の内容に至るまで、
など、多くのGemのソースコードを読みにいき、とても勉強になりました(と同時に、Capistrano辛いから早くやめたいという気持ちもさらに強くなりましたw)。
「なんか動いた!OK!」のフェーズから、「なぜうまくいったのだろう?」とソースコードを読みに行くフェーズを経ることで、学びは5倍10倍になるんだなあということを改めて実感しました。
参考記事
- Rails の初期化プロセス - Railsガイド
- 「
rails server
コマンドを打ってから初期化されるまでに何が起こっているか?」はRailsガイドにめちゃくちゃ詳しく書かれていました。
- 「
- capistrano3でpumaの運用ー設定ファイルの管理どうする? - Qiita
- 「rails server」コマンドを読み解く - Qiita