NestJS+Nginx部署后静态资源404问题的排查与解决
问题解决:NestJS静态资源在Nginx反向代理下返回404
核心问题分析
本地/构建模式下静态资源可正常访问,部署到EC2+Nginx+PM2后仅静态资源404,说明问题出在Nginx配置转发逻辑、服务器目录权限或NestJS构建后路径匹配这三个环节。
解决方案
1. 修正Nginx配置(优先推荐)
Nginx的location块不能嵌套,且需确保静态资源请求要么直接由Nginx处理(性能更优),要么正确转发给NestJS。
选项A:让Nginx直接提供静态资源(推荐)
直接让Nginx读取服务器上的静态文件,无需经过NestJS,减少请求链路:
server { server_name domain.tld; include /etc/nginx/default.d/*.conf; # 处理静态资源请求 location /uploads/ { # 替换为EC2上你的项目storage目录实际路径,比如/home/ubuntu/Project/storage root /path/to/Project/storage; # 文件不存在时 fallback 到NestJS(可选) try_files $uri $uri/ @nestjs; } # 其他请求转发给NestJS location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_cache_bypass $http_upgrade; } # 备用规则:静态文件不存在时转发给NestJS location @nestjs { proxy_pass http://127.0.0.1:3000; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; } listen 443 ssl http2; # managed by Certbot ssl_certificate /certpath/domain.tld/fullchain.pem; # managed by Certbot ssl_certificate_key /certpath/domain.tld/privkey.pem; # managed by Certbot } server { if ($host = domain.tld) { return 301 https://$host$request_uri; } # managed by Certbot server_name domain.tld; listen 80; return 404; # managed by Certbot }
选项B:确保静态资源请求转发到NestJS
如果需要NestJS处理静态资源逻辑(比如权限校验),添加独立的location块转发请求:
server { server_name domain.tld; include /etc/nginx/default.d/*.conf; # 单独转发静态资源请求到NestJS location /uploads/ { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:3000; } location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_cache_bypass $http_upgrade; } listen 443 ssl http2; # managed by Certbot ssl_certificate /certpath/domain.tld/fullchain.pem; ssl_certificate_key /certpath/domain.tld/privkey.pem; }
2. 修复服务器目录权限
EC2上的storage目录权限可能限制了PM2进程读取文件:
# 进入项目根目录 cd /path/to/Project # 将目录权限设置为当前部署用户(比如ubuntu) sudo chown -R $USER:$USER storage # 设置可读可执行权限 sudo chmod -R 755 storage
3. 验证NestJS构建后路径配置
确认构建后的ServeStaticModule路径是否正确,可临时添加日志验证:
// 在AppModule中添加 import { join } from 'path'; console.log('静态资源根路径:', join(__dirname, '..', '..', 'storage'));
查看PM2日志确认路径是否为EC2上实际的storage目录:
pm2 logs your-app-name
如果路径错误,调整join参数(比如构建后dist目录结构变化,可能需要改为join(__dirname, '..', 'storage'))。
验证操作
- 重新加载Nginx配置:
sudo nginx -s reload
- 重启PM2应用:
pm2 restart your-app-name
- 访问静态资源URL,检查是否返回200状态码。
内容的提问来源于stack exchange,提问作者Md. A. Apu
相关产品推荐
相关产品推荐

