stdout_redirect
不能正常工作的原因是当你运行 rails server -d
时,config/puma.rb
没有被执行。你可以通过更改端口号或在文件中引入语法错误来证明这一点。
Puma 作为一个 Rack 服务器运行,因此由 Rack 中间件启动。 Rack 代码 只使用 Ruby 核心库中的 Process
类将进程分离:
def daemonize_app
Process.daemon
end
不幸的是,Process.daemon
默认会执行两个操作:
- 将当前工作目录更改为根目录('/')。
- 将stdout和stderr重定向到
/dev/null
。
因此,在Puma服务器初始化时,所有进程输出都被丢弃,由于/config/puma.rb
不存在,因此Puma会回退到其硬编码的默认设置。
如果您暂时修改rack
代码以覆盖chdir行为,您实际上可以演示所需的行为:
def daemonize_app
Process.daemon(true)
end
如果
.daemon
的第一个参数为
true
,它不会更改当前工作目录,因此
config/puma.rb
会被执行。
除了对Rack进行一些丑陋的猴子补丁之外,可能的解决方法是跳过
-d
选项并在
config/puma.rb
中自行创建。例如:
return unless ENV['DAEMONIZE_PUMA'].present?
puts 'Running puma as a daemon...'
Process.daemon(true)
接下来:
% export DAEMONIZE_PUMA=true
% rails server
=> Booting Puma
=> Rails 6.1.4 application starting in development
=> Run `bin/rails server --help` for more startup options
Running puma as a daemon...
% tail log/puma.out
=== puma startup: 2021-07-17 10:03:37 +1200 ===