Rails应用部署在Nginx Passenger服务器中图片无法加载问题
你遇到的这个问题很典型——CSS和JS能正常加载,但图片找不到,大概率是assets预编译、配置或者文件访问层面的问题。我之前帮不少开发者排查过类似情况,下面是几个最关键的排查和解决步骤:
1. 确认Assets预编译已完成
生产环境下Rails不会自动编译静态资源,必须手动执行预编译命令,确保图片被打包到/public/assets/目录:
RAILS_ENV=production bundle exec rake assets:precompile
执行完后去/public/assets/目录看看,应该能找到带指纹后缀的图片文件(比如logo-abc123def.png),这说明预编译成功了。
2. 检查Production.rb的关键配置
你的配置片段没写完,重点确认这几个参数:
Rails.application.configure do # 确保静态文件服务开启 config.public_file_server.enabled = true # 开启assets指纹(生产环境推荐开启,利于缓存) config.assets.digest = true # 生产环境建议设为false(预编译后不需要动态编译) config.assets.compile = false end
如果临时想测试动态编译,可以把config.assets.compile设为true,但不建议长期在生产环境使用,会影响性能。
3. 验证Nginx配置是否正确
Nginx需要正确指向你的应用public目录,并且优先处理/assets/下的静态文件。检查你的Nginx server配置块:
server { listen 80; server_name your-domain.com; # 必须指向应用的public目录 root /path/to/your/rails-app/public; passenger_enabled on; passenger_app_root /path/to/your/rails-app; passenger_ruby /path/to/your/ruby-executable; # 比如 /usr/local/rbenv/shims/ruby # 让Nginx直接处理assets,提升性能并避免Passenger拦截 location ~ ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break; } }
修改配置后记得重启Nginx:sudo service nginx restart
4. 检查视图中图片的引用方式
一定要用Rails提供的image_tag辅助方法,而不是硬编码路径:
# 正确写法 <%= image_tag('logo.png') %> # 错误写法(硬编码路径,无法适配指纹文件名) <img src="/assets/logo.png">
image_tag会自动根据预编译后的指纹文件名生成正确的URL,确保图片能被找到。
5. 确认文件权限
确保/public/assets/目录及其下的文件能被Nginx/Passenger的运行用户读取:
# 设置文件权限为可读 chmod -R 644 /path/to/your/rails-app/public/assets # 设置目录权限为可访问 chmod -R 755 /path/to/your/rails-app/public/assets
通常Nginx的运行用户是www-data,你可以用ps aux | grep nginx确认。
6. 清理缓存并重启应用
有时候旧的缓存会导致资源路径异常,执行以下命令清理缓存:
RAILS_ENV=production bundle exec rake tmp:cache:clear
然后重启Passenger应用:
passenger-config restart-app /path/to/your/rails-app
按照上面的步骤一步步排查,应该能解决图片无法显示的问题。
内容的提问来源于stack exchange,提问作者Karthik Muthu

