我在使用 Nestjs 时遇到问题,该请求来自 nginx 的 proxy_pass 和 docker-compose。
我有一个 Nestjs 服务,它通过以下端点侦听端口 3000
我有以下 nginx 配置
events {
worker_connections 1024;
}
http {
upstream ticketing_users {
server ticketing_users:3000;
}
server {
listen 80;
server_name ticketing.dev;
location ~ ^/api/users(.*)$ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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-Host $server_name;
proxy_intercept_errors on;
proxy_pass http://ticketing_users/;
}
access_log /var/logs/nginx/access_log access;
error_log /var/logs/nginx/error.log error;
}
}
这是我在 docker-compose.yaml 中的 nginx 配置:
reverse-proxy:
image: nginx
volumes:
- ./docker/nginx.conf:/etc/nginx/nginx.conf
- ./docker/nginx:/var/logs/nginx
networks:
- ticketing.dev
ports:
- 8080:80
depends_on:
- ticketing_users
links:
- ticketing_users
这是我的 main.ts :
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(UsersModule, {
cors: true,
logger: ['verbose', 'debug', 'error', 'warn']
});
app.set('trust proxy', true);
app.use(morgan('combined'));
app.setGlobalPrefix('api');
await app.listen(3000);
}
bootstrap();
和我的控制器(使用 cli 生成,因此在模块中声明):
@Controller('users')
export class UsersController {
@Get(':id')
public findById(@Param('id') id: string): string {
return id;
}
}
我已经在我的主机文件中设置了ticketing.dev。 但是当我用邮递员查询示例
get http://ticketing.dev:8080/api/users/1234
时,我总是得到相同的结果,我尝试放置一些 console.logs 但没有出现:
{ “状态代码”:404, "message": "无法获取 /api/users/1234", “错误”:“未找到”}
但是摩根中间件正确处理请求并显示:
GET /api/users/test 404 0.496 毫秒 - 77
我做错了什么?
我想我发现了问题——它出在你的 nginx 位置配置中。问题在于 proxy_pass URL 如何处理路径重写。
当前配置:
location ~ ^/api/users(.*)$ {
proxy_pass http://ticketing_users/;
}
当您向 proxy_pass 添加尾部斜杠时,nginx 会删除匹配的位置路径。这意味着您的
/api/users/1234
请求将被重写为 /1234
,但您的 NestJS 应用程序需要 /api/users/1234
。
这里有两种方法可以解决这个问题:
location ~ ^/api/users(.*)$ {
proxy_pass http://ticketing_users$1;
}
location ~ ^/api/users(.*)$ {
proxy_pass http://ticketing_users/api/users$1;
}
任一解决方案都将确保完整路径
/api/users/1234
到达您的 NestJS 应用程序。
此外,请确保您的 docker-compose 网络配置正确。将其添加到您的 Ticketing_users 服务中:
networks:
- ticketing.dev
要在将来调试类似的问题,您可以将这些添加到您的 nginx 配置中以准确查看正在传递的内容:
add_header X-Original-URI $request_uri;
add_header X-Proxy-Pass-URI $uri;
如果有效请告诉我!