我在坐在Web应用程序前面的Docker中使用nginx作为反向代理,除了POST请求之外,它大部分都在工作。我需要能够接受来自任何URL和端口的连接,并将其代理到Web应用程序的特定主机名和端口。这适用于普通的Web请求,但对于POST则分崩离析。这是我的nginx.conf:
server {
listen *:8080;
server_name _;
proxy_set_header Host 127.0.0.1:8080;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $proxy_host;
proxy_set_header X-Real-IP 127.0.0.1;
location / {
proxy_pass http://example.com:8080/
rewrite "^(/.+?):\d+?/(.+?)$" $1:8080/$2 break;
}
}
服务器仅在验证用户身份时接受来自127.0.0.1:8080
的连接。我使用的是nginx:1.13.6-alpine。感谢。
修改
以下是来自Web服务器的示例日志输出:
17:11:26,435 INFO [stdout] (http-0.0.0.0:8080-1) javax.servlet.ServletException: CORS origin denied 127.0.0.1:7001 not on allowed list:[]
以下是nginx容器的日志条目:
172.18.0.1 - - [02/Nov/2017:17:11:26 +0000] "POST /suite/auth?environment=tempo HTTP/1.1" 401 996 "http://127.0.0.1:7001/suite/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36" "-"
我试图在Docker Swarm集群中启动Web应用程序的多个实例,但我没有能力动态分配IP地址或主机名,所以我打算使用唯一的端口号对于每个实例。我试图让nginx代理我的请求,以便我可以启动尽可能多的唯一实例。
答案 0 :(得分:0)
所以我想出了这一点,希望我发现的将帮助其他人。我最后以不同的方式解决了这个问题;我没有尝试重写HTTP头中的端口,而是使用nginx中的sub_filter
插件来重写应用程序在通过代理时所服务的HTML。这样,HTML中的所有链接都使用正确的域和端口。这是最终为我工作的配置:
server {
listen 7001 default_server;
server_name _;
location / {
proxy_pass http://app:8080/;
proxy_redirect http://127.0.0.1:8080/ http://$host/;
proxy_set_header Accept-Encoding "";
proxy_set_header Host $host;
proxy_set_header Origin 127.0.0.1:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $proxy_host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
sub_filter_once off;
sub_filter_types *;
sub_filter "127.0.0.1:8080" "$host";
}
}
作为参考,我的docker-compose.yml
文件的简化版本如下所示:
version: "3.3"
services:
app:
image: my-application:latest
depends_on:
- db
db:
image: mysql:latest
nginx:
image: nginx:1.13.6-alpine
ports:
- "80:7001"
volumes:
- ./nginx-config.conf:/etc/nginx/conf.d/nginx-config.conf
depends_on:
- app