railsのプロジェクトをnginx経由で接続できるようにするにあたって、ソケット通信で起動しようとしてもなぜかbindの設定がうまく機能してくれなかった
gemのソースを辿って原因が見つかったのと、調べている中で同じような問題に直面して質問している人が少しいたのでメモとして残しておく
結論
ENV['HOST']
に値が設定されていると、rails server
コマンドで起動した際に、config/puma.rb
で設定したソケットのbind設定は上書きされてしまい機能しなくなる
そのため、ENV['HOST']
の設定を削除するか、bundle exec puma
で起動するとソケットのbind設定が機能する
概要
socket = Rails.root.join('tmp/sockets/puma.sock')
bind "unix://#{socket}"
nginxとのソケット通信のために、上記の設定を入れていたが、railsのサーバーを起動すると
* Listening on unix:///work/tmp/sockets/puma.sock
となってほしいはずが
* Listening on http://0.0.0.0:3000
だけが表示されてソケット通信ができていなかった
原因についてもう少し書くと、ENV['HOST']
が設定されている場合、rails serverで起動する際にRack::Server::initializeの引数に以下のようなパラメータが渡ってしまう
"{:user_supplied_options=>[:Host], :server=>nil, :log_stdout=>false, :Port=>3000,
:Host=>\"0.0.0.0\", :DoNotReverseLookup=>true, :config=>\"config.ru\",
:environment=>\"production\", :daemonize=>false,
:pid=>\"/work/tmp/pids/server.pid\",:caching=>nil,
:restart_cmd=>\"bin/rails server --restart\", :early_hints=>nil}"
:user_supplied_options=>[:Host]
が存在するためにその後の、Puma::Configuration::initializeにHostのパラメータがuser_optionsとして渡されてしまう
{:Host=>"0.0.0.0"}
これによって、config/puma.rb
から読み込まれた設定であるfile_options
とは別に、user_options
から作成された設定にbindsキーが、pumaに渡される設定として同時に存在する状態になってしまった
@file_options={:min_threads=>5, :max_threads=>5, :binds=>["unix:///work/tmp/sockets/puma.sock"], :environment=>"production", :pidfile=>"tmp/pids/server.pid"},
@user_options=
{:Host=>"0.0.0.0",
:binds=>["tcp://0.0.0.0:3000"],
pumaはconfig/puma.rb
ファイルから読み込んだ設定であるfile_optionsよりも、user_optionsとして渡されたパラメータを後にmergeしたものを最終的な設定とするようなっていたため、file_optionsのbindsの設定が上書きされてしまっていた
def final_options
default_options
.merge(file_options)
.merge(user_options)
end
ENV['HOST']
を削除することで、:user_supplied_options=>[]
になるので、user_optionsが空の配列{}
になり、無事config/puma.rb
の設定が上書きされずに適用されるようになった
"{:user_supplied_options=>[], :server=>nil, :log_stdout=>false, :Port=>3000,
:Host=>\"0.0.0.0\", :DoNotReverseLookup=>true, :config=>\"config.ru\",
:environment=>\"production\", :daemonize=>false,
:pid=>\"/work/tmp/pids/server.pid\", :caching=>nil,
:restart_cmd=>\"bin/rails server --restart\", :early_hints=>nil}"