Rails生产环境部署异常:日志丢失及资产管道问题排查
问题场景
capistrano 3.19.1、rails 7.1.3,将应用部署至两台独立VPS的开发与生产环境:开发环境部署运行正常,生产环境出现两个异常:
- 前端页面提示“something went wrong”
- 找不到
production.log日志文件
已完成的初步排查:
- Nginx路由配置正常,Passenger无报错
deploy/[environment].rb文件指向的部署目录正确,所有应用文件已同步到位- 手动在日志目录执行
touch production.log(权限设为-rw-rw-rw-),并执行touch tmp/restart.txt重启应用后,日志文件仍无内容写入 - 进入生产环境控制台执行
Rails.logger,返回结果显示日志输出指向STDOUT而非文件:
$ RAILS_ENV=production bundle exec rails c > Rails.logger => #<ActiveSupport::BroadcastLogger:0x00007f1c625c0a78 @broadcasts= [#<ActiveSupport::Logger:0x00007f1c625e73f8 @default_formatter=#<Logger::Formatter:0x00007f1c625cb9f0 @datetime_format=nil>, @formatter=#<Logger::Formatter:0x00007f1c625c9a38 @datetime_format=nil>, @level=1, @level_override={}, @logdev= #<Logger::LogDevice:0x00007f1c625e80c8 @binmode=false, @dev=#<IO:<STDOUT>>, @filename=nil, @mon_data=#<Monitor:0x00007f1c625cb928>, @mon_data_owner_object_id=4960, @shift_age=nil, @shift_period_suffix=nil, @shift_size=nil>, @progname=nil>], @formatter=#<Logger::Formatter:0x00007f1c625c9a38 @datetime_format=nil>, @progname="Broadcast">
日志丢失的排查方向
- Rails日志配置检查
- 查看
config/environments/production.rb中的日志配置,确认是否正确设置了config.logger或config.log_path,是否存在覆盖默认日志文件路径的配置 - 检查是否有第三方日志gem(如
lograge、fluentd)修改了日志输出目标,导致日志不再写入production.log
- 查看
- 进程权限与目录权限
- 确认Passenger运行的系统用户是否拥有日志目录的读写权限(即使文件权限是
-rw-rw-rw-,目录权限可能限制了进程写入) - 检查
tmp目录权限,Passenger需要该目录的写入权限来处理重启信号和临时文件
- 确认Passenger运行的系统用户是否拥有日志目录的读写权限(即使文件权限是
- Capistrano部署配置
- 检查Capistrano的日志相关任务,是否在部署过程中修改了日志文件的权限或路径
- 确认
deploy.rb或production.rb中是否有自定义的日志处理逻辑,覆盖了默认行为
- Passenger/Nginx日志转发配置
- Passenger在生产环境默认会将Rails的STDOUT/STDERR输出转发到Nginx的日志文件中,这可能是日志出现在
/var/log/nginx.error.log的原因。可检查Passenger配置是否开启了passenger_log_level或相关日志转发设置
- Passenger在生产环境默认会将Rails的STDOUT/STDERR输出转发到Nginx的日志文件中,这可能是日志出现在
后续疑问解答
1. 为什么资产预编译未自动执行?
Capistrano默认会在部署过程中触发资产预编译,但以下情况会导致自动预编译失效:
deploy.rb中禁用了资产预编译任务(如设置set :assets_precompile, false)- 部署过程中Capistrano检测到资产文件未发生变化,跳过了预编译步骤(可通过部署日志确认是否有
Skipping asset precompile的提示) - 生产环境的bundle中缺少预编译所需的依赖(如
sprocketsgem未正确安装) - 部署用户的权限不足,无法执行预编译命令或写入
public/assets目录
2. 为什么日志会写入Nginx错误日志?
Rails 7在生产环境默认的日志配置中,当应用通过Passenger/Nginx运行时,Passenger会捕获Rails的STDOUT/STDERR输出,并将其转发到Nginx的日志文件中。这是因为Passenger作为应用服务器,会接管应用的标准输出,统一汇总到Web服务器的日志体系中。而开发环境通常使用rails server运行,日志直接输出到控制台或指定的开发日志文件,因此表现不同。
3. 同一deploy.rb为何开发与生产环境表现不同?
Capistrano会根据环境加载对应的配置文件(deploy/development.rb和deploy/production.rb),即使deploy.rb相同,环境专属配置可能存在差异:
- 生产环境可能启用了更严格的权限控制、资产压缩或日志转发配置
- 开发环境可能跳过了某些生产环境的强制检查(如资产预编译、缓存清理)
- 环境变量差异:生产环境可能设置了不同的
RAILS_ENV、SECRET_KEY_BASE等变量,影响应用的日志和资产处理逻辑
内容的提问来源于stack exchange,提问作者Jerome
相关产品推荐
相关产品推荐

