Docker部署Rails应用搭配Nginx反向代理无法访问assets静态资源
问题核心原因
你遇到的404是两个配置缺失共同导致的:
- Rails生产环境默认关闭了静态资源服务,
config.public_file_server.enabled参数默认为false,收到静态资源请求后不会主动返回对应文件 - 你当前Nginx部署在宿主机,无法直接读取Docker容器内部存储的静态资源文件,所以也没办法由Nginx直接返回资源
方案1:开启Rails静态资源服务(快速临时解决)
适合测试场景或者小流量站点,无需修改Nginx配置:
- 启动容器时新增环境变量
RAILS_SERVE_STATIC_FILES=true,Rails收到该变量后会自动开启静态资源服务,所有请求包括静态资源都由Rails直接处理 - 修改后的启动命令如下:
sudo docker run -p 3000:3000 -e DATABASE_NAME=dbname -e DATABASE_USER=dbuser -e DATABASE_PASSWORD=dbpassword -e RAILS_ENV=production -e DATABASE_HOST=my_ip -e RAILS_SERVE_STATIC_FILES=true -d 72b09817c012
方案2:Nginx处理静态资源(生产环境推荐)
性能更优,静态资源直接由Nginx返回,无需经过Rails处理:
- 启动容器时新增目录挂载参数,把容器内的静态资源目录映射到宿主机,让Nginx可以读取到:
sudo docker run -p 3000:3000 -v /var/www/myapp/public:/app/public -e DATABASE_NAME=dbname -e DATABASE_USER=dbuser -e DATABASE_PASSWORD=dbpassword -e RAILS_ENV=production -e DATABASE_HOST=my_ip -d 72b09817c012
- 修改Nginx站点配置,新增静态资源匹配规则:
server { server_name mywebsite.com; # 新增静态资源匹配规则 location ~ ^/(assets|packs)/ { root /var/www/myapp/public; expires 1y; add_header Cache-Control "public, immutable"; } location / { proxy_pass http://localhost:3000; # 建议补充以下代理头,方便Rails获取客户端真实信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } # 原80端口跳转配置无需修改
- 执行
sudo nginx -s reload重启Nginx生效。
注意:如果后续更新镜像重新部署,建议提前清空宿主机
/var/www/myapp/public下的旧静态资源,避免缓存异常。
内容的提问来源于stack exchange,提问作者Marcin Doliwa
相关产品推荐
相关产品推荐

