Docker-Compose下NestJS无法处理Nginx proxy_pass请求问题排查
解决Docker-Compose下Nginx转发NestJS请求404问题
Morgan能捕获请求但无业务日志、返回404,核心是请求路径在转发后和NestJS路由不匹配,下面是针对性的排查和解决步骤:
1. 修正Nginx的proxy_pass配置(最常见诱因)
如果Nginx的proxy_pass末尾带了斜杠,会自动截断请求前缀,导致路径重写错误:
# 错误配置:会把/api/users/1234转发成http://nestjs:3000/users/1234 location /api/ { proxy_pass http://nestjs:3000/; }
NestJS的路由是/api/users,收到/users/1234自然匹配不到。正确配置要去掉末尾斜杠,保留完整路径转发:
location /api/ { proxy_pass http://nestjs:3000; # 补充代理头,确保NestJS能获取正确的请求上下文 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; }
2. 确认NestJS的路由前缀配置
检查路由前缀是否和转发路径匹配:
- 如果设置了全局前缀,在
main.ts中确认:
async function bootstrap() { const app = await NestFactory.create(AppModule); app.setGlobalPrefix('api'); // 全局添加/api前缀,控制器只需写'users' await app.listen(3000); } bootstrap();
- 控制器路由要对应:
@Controller('users') // 配合全局前缀,对应/api/users export class UsersController { @Get(':id') getUser(@Param('id') id: string) { console.log(`处理用户请求:${id}`); // 确保业务日志存在 return { id, name: '测试用户' }; } }
如果没设全局前缀,控制器要写完整路径@Controller('api/users')。
3. 验证Docker-Compose网络连通性
确保Nginx和NestJS在同一网络,用服务名而非localhost访问:
version: '3.8' services: nestjs: build: ./nestjs-service networks: - app-network nginx: image: nginx:alpine ports: - "8080:80" volumes: - ./nginx/conf.d:/etc/nginx/conf.d depends_on: - nestjs networks: - app-network networks: app-network: driver: bridge
容器内的localhost指向自身,必须用服务名nestjs才能访问到NestJS容器。
4. 调试实际请求路径
在NestJS中添加全局中间件,打印实际收到的路径:
app.use((req, res, next) => { console.log(`实际收到请求路径:${req.path}`); next(); });
如果打印的是/users/1234,说明Nginx的proxy_pass带了斜杠;如果是/api/users/1234,则检查路由前缀是否对应。
5. 检查Nginx请求日志
开启Nginx日志,确认转发细节:
http { access_log /var/log/nginx/access.log; server { listen 80; server_name ticketing.dev; location /api/ { proxy_pass http://nestjs:3000; proxy_set_header Host $host; } } }
进入容器查看日志:
docker-compose exec nginx cat /var/log/nginx/access.log
通过日志确认请求路径和转发目标是否正确。
内容的提问来源于stack exchange,提问作者Julien METRAL
相关产品推荐
相关产品推荐

