Docker Nginx反向代理不重定向? 更新
这个问题的细节越来越长,但我认为它的范围缩小到:Docker Nginx反向代理不重定向? 更新,docker,nginx,docker-compose,nginx-reverse-proxy,gogs,Docker,Nginx,Docker Compose,Nginx Reverse Proxy,Gogs,这个问题的细节越来越长,但我认为它的范围缩小到: 出于某种原因,当Nginx试图确定是否代理请求时,主机名对它很重要。如果主机名设置为git.example.com,则请求似乎不会通过,但如果主机名设置为203.0.113.2,则请求会通过。为什么主机名很重要 及 原始问题的开始 当我直接在浏览器栏中输入反向代理的IP地址时,它会执行重定向 使用通过/etc/hosts条目203.0.113.2 git.example.com解析的URL时,将显示“欢迎使用Ngnix页面”。有什么想法吗?以下
出于某种原因,当Nginx试图确定是否代理请求时,主机名对它很重要。如果主机名设置为
git.example.com
,则请求似乎不会通过,但如果主机名设置为203.0.113.2
,则请求会通过。为什么主机名很重要
及
原始问题的开始
当我直接在浏览器栏中输入反向代理的IP地址时,它会执行重定向
使用通过/etc/hosts
条目203.0.113.2 git.example.com
解析的URL时,将显示“欢迎使用Ngnix页面”。有什么想法吗?以下是配置:
server {
listen 203.0.113.2:80 default_server;
server_name 203.0.113.2 git.example.com;
proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
location / {
proxy_pass http://203.0.113.1:3000;
}
}
这是用于启动整个程序的docker compose.yml
文件:
version: '3'
services:
gogs-nginx:
build: ./proxy
ports:
- "80:80"
networks:
mk1net:
ipv4_address: 203.0.113.2
gogs:
image: gogs/gogs
ports:
- "3000:3000"
volumes:
- gogs-data:/data
networks:
mk1net:
ipv4_address: 203.0.113.3
volumes:
gogs-data:
external: true
networks:
mk1net:
ipam:
config:
- subnet: 203.0.113.0/24
一件有趣的事情是,我可以导航到例如:
http://203.0.113.2/issues
上述URL的日志为:
gogs-nginx|U 1 | 203.0.113.1---[07/Oct/2018:11:28:06+0000]“GET/HTTP/1.1”200 38825“-”Mozilla/5.0(X11;Linux x86|U 64)AppleWebKit/537.36(KHTML,类似Gecko)Chrome/69.0.3497.100 Safari/537.36“-”
如果我随后用git.example.com
更改203.0.113.2
(这样url最后变成git.example.com
我会得到Nginxs“404未找到”页面,日志显示:
gogs-nginx_1 | 2018/10/07 11:31:34[错误]8#8:*10 open()“/usr/share/nginx/html/issues”失败(2:没有这样的文件或目录),客户端:203.0.113.1,服务器:localhost,请求:“GET/issues HTTP/1.1”,主机:“git.example.com”
如果我只使用http://git.example.com
作为URL,我获得了NGINX欢迎页面和以下日志:
gogs-nginx|u 1 | 203.0.113.1---[07/Oct/2018:11:34:39+0000]“GET/HTTP/1.1”304 0“-”Mozilla/5.0(X11;Linux x86_64)AppleWebKit/537.36(KHTML,类似Gecko)Chrome/69.0.3497.100 Safari/537.36“-”
看起来Nginx理解请求是针对代理的,因为它记录代理的IP,但它不会重定向到代理并返回304
使用Curl执行请求
将curl与主机名参数一起使用,以代理为目标,如下所示:
curl -H 'Host: git.example.com' -si http://203.0.113.2
curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
Nginx欢迎页面中的结果:
ole@mki:~/Gogs/.gogs/docker$ curl -H 'Host: git.example.com' -si http://203.0.113.2
HTTP/1.1 200 OK
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:09:11 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Jul 2018 13:27:08 GMT
Connection: keep-alive
ETag: "5b3b79ac-264"
Accept-Ranges: bytes
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
然后,代理按其应有的方式工作:
ole@mki:~/Gogs/.gogs/docker$ curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
HTTP/1.1 302 Found
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:14:46 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 34
Connection: keep-alive
Location: /user/login
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=845bb09d69587b81; Path=/; HttpOnly
Set-Cookie: _csrf=neGgBfG4LdOcdrdeA0snHjVGz4s6MTUzODkzMjQ4NjE5MzEzNzI3OQ%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 17:14:46 GMT; HttpOnly
Set-Cookie: redirect_to=%252F; Path=/
<a href="/user/login">Found</a>.
ole@mki:~/Gogs/.Gogs/docker$curl-H'主机:203.0.113.2'-sihttp://203.0.113.2
找到HTTP/1.1 302
服务器:nginx/1.15.1
日期:2018年10月7日星期日17:14:46 GMT
内容类型:text/html;字符集=utf-8
内容长度:34
连接:保持活力
位置:/user/登录
设置Cookie:lang=en US;Path=/;Max Age=2147483647
设置Cookie:i_like_gogits=845bb09d69587b81;Path=/;HttpOnly
设置Cookie:_csrf=neGgBfG4LdOcdrdeA0snHjVGz4s6MTUzODkzMjQ4NjE5MzEzNzI3OQ%3D%3D;Path=/;Expires=Mon,2018年10月8日17:14:46 GMT;仅限http
设置Cookie:将\u重定向到=%252F;路径=/
.
很抱歉,我没有意识到您这边发生了什么,因为这些信息有时令人困惑,有时不完整。但是Stackoverflow提供了一个很好的解释,说明了什么是一个好问题:因此我刚刚尝试实现了一个您可能要构建的系统的最小示例
下面我提供了所有文件,并将向您展示一个测试运行
文件#1:docker compose.yml
我的电脑上有过时的Docker,我不想打扰Docker网络,所以我刚刚使用Docker链接链接了两个容器。这是最重要的部分,链接将确保(1)我们的web
容器依赖于gogs
;(2)我们可以从web
内部引用gogs
IP,就像gogs
一样。Docker将把名称解析为分配给容器的IP
因为我只需要一个简单的例子,所以我跳过了所有与此无关的内容。例如,volume
文件#2:Dockerfile
较新的撰写版本支持在docker Compose.yml
中正确指定的config
选项,但我需要一个自定义Dockerfile
。它很简单:
FROM nginx:stable-alpine
COPY gogs.conf /etc/nginx/conf.d
文件#3:gogs.conf
最后,我们需要为代理配置Nginx:
server {
listen 80 default_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://gogs:3000;
}
}
您可能会注意到,这里我们仅通过名称gogs
引用另一个容器,我们需要知道它暴露的端口号。我们知道:3000
跑步
它已启动并运行:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f74293df630 g_web "nginx -g 'daemon off" 2 minutes ago Up 26 seconds 0.0.0.0:8000->80/tcp g_web_1
dfa2dbaa6074 gogs/gogs "/app/gogs/docker/sta" 2 minutes ago Up 26 seconds 22/tcp, 3000/tcp g_gogs_1
web
集装箱在8000号港口对外开放
测验
通过IP
让我们通过IP请求它:
$ curl -si http://192.168.99.100:8000/
HTTP/1.1 302 Found
Server: nginx/1.14.0
Date: Sun, 07 Oct 2018 15:13:55 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 31
Connection: keep-alive
Location: /install
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=50411f542e2ae8f8; Path=/; HttpOnly
Set-Cookie: _csrf=ZJxRPqnqayIbpAYgZ22zrPIOaSo6MTUzODkyNTIzNTQ2NTg5MDE1NA%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 15:13:55 GMT; HttpOnly
<a href="/install">Found</a>.
我可以从日志中看到:(1)两个容器都可以工作,它们被用来处理请求;(2)192.168.99.1是我的主机的IP地址,这意味着“gogs”通过X-Forwarded-For
成功地获得了一个真正的请求IP
按域名
好的,让我们使用域名请求:
$ curl -H 'Host: g.example.com' -si http://192.168.99.100:8000/
相信我,这就足够了。Host
是传递域名的HTTP协议头。任何浏览器都会在引擎盖下这样做
相应的日志文件是--
没有变化,一切都按预期进行。很抱歉,我没有意识到您这边发生了什么,因为信息有时令人困惑,有时不完整。但是Stackoverflow对什么是好问题提供了很好的解释:因此我刚刚尝试实现了一个最小的系统示例很可能会建造 下面我提供了所有文件,并将向您展示一个测试运行 文件#1:
docker compose.yml
我的电脑上有过时的Docker,我不想打扰Docker网络,所以我刚刚使用Docker链接链接了两个容器。这是最重要的部分,链接将确保(1)我们的web
容器依赖于gogs
;(2)我们可以从web
内部引用gogs
IP,就像gogs
一样。Docker将解决此问题
$ curl -si http://192.168.99.100:8000/
HTTP/1.1 302 Found
Server: nginx/1.14.0
Date: Sun, 07 Oct 2018 15:13:55 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 31
Connection: keep-alive
Location: /install
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=50411f542e2ae8f8; Path=/; HttpOnly
Set-Cookie: _csrf=ZJxRPqnqayIbpAYgZ22zrPIOaSo6MTUzODkyNTIzNTQ2NTg5MDE1NA%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 15:13:55 GMT; HttpOnly
<a href="/install">Found</a>.
web_1 | 192.168.99.1 - - [07/Oct/2018:15:14:24 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"
gogs_1 | [Macaron] 2018-10-07 15:14:24: Started GET / for 192.168.99.1
gogs_1 | [Macaron] 2018-10-07 15:14:24: Completed GET / 302 Found in 199.519µs
gogs_1 | 2018/10/07 15:14:24 [TRACE] Session ID: 38d06d393a9e9d21
gogs_1 | 2018/10/07 15:14:24 [TRACE] CSRF Token: Xth986dFWhhj8w8vBdIqRZu4SbI6MTUzODkyNTI2NDYxMDYzNzAyNA==
$ curl -H 'Host: g.example.com' -si http://192.168.99.100:8000/
gogs_1 | [Macaron] 2018-10-07 15:32:49: Started GET / for 192.168.99.1
gogs_1 | [Macaron] 2018-10-07 15:32:49: Completed GET / 302 Found in 618.701µs
gogs_1 | 2018/10/07 15:32:49 [TRACE] Session ID: 81f64d97e9c3dd1e
gogs_1 | 2018/10/07 15:32:49 [TRACE] CSRF Token: X5QyHM4LMIfn8OSJD1gwSSEyXV46MTUzODkyNjM2OTgyODQyMjExMA==
web_1 | 192.168.99.1 - - [07/Oct/2018:15:32:49 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"