使用Nginx作为反向代理时连接到上游时拒绝连接
设置如下:我有一个在0.0.0.0:8000
上运行的Gunicorn/Django应用,可通过浏览器访问.为了提供静态文件,我将nginx作为反向代理运行. /etc/nginx/nginx.conf
配置为转发请求,如下所示:
The setup is as follows: I have a Gunicorn/Django app running on 0.0.0.0:8000
that is accessible via the browser. To serve static files I am running nginx as a reverse proxy. /etc/nginx/nginx.conf
is configured to forward requests as follows:
server {
location /static/ {
alias /data/www/;
}
# Proxying the connections
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass http://0.0.0.0:8000;
}
}
和我的docker-compose.yml
文件如下:
version: '3.3'
services:
web:
restart: always
build: ./web
expose:
- "8000"
ports:
- "8000:8000"
volumes:
- staticdata:/usr/src/app/static_files
command: gunicorn wsgi:application --workers 2 --bind 0.0.0.0:8000
depends_on:
- postgres
nginx:
restart: always
build: ./nginx
ports:
- "80:80"
- "443:443"
volumes:
- staticdata:/data/www
depends_on:
- web
postgres:
image: postgres:9.2
restart: always
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
staticdata:
pgdata:
当我通过浏览器访问0.0.0.0:8000
时,该应用程序运行正常(尽管不提供静态文件),但是当我访问127.0.0.1:80
时,出现以下错误:
When I visit 0.0.0.0:8000
via the browser the application works fine (albeit without serving static files), but when I visit 127.0.0.1:80
I get the following error:
nginx_1 | 2017/09/17 13:59:46 [error] 6#6: *5 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8000/", host: "127.0.0.1"
我知道此错误表明在0.0.0.0:8000
上运行的服务器未接受请求,但是由于我可以通过浏览器访问它,所以我有点困惑.
I know that this error indicates that the server running on 0.0.0.0:8000
is not accepting requests, but since I can visit it via the browser I am a bit confused.
谢谢.
从以下位置更改您的proxy_pass
Change your proxy_pass from
proxy_pass http://0.0.0.0:8000;
到
proxy_pass http://web:8000;
您的nginx需要转发以请求Web容器
Your nginx needs to forward to request the web container
说明
0.0.0.0
是一个特殊的IP地址,用于引用机器上任何可用的接口.因此,如果您的计算机具有环回(lo),以太网(eth0),Wifi(wlan0),且其IP分别为127.0.0.1
,192.168.0.100
,10.0.0.100
.
0.0.0.0
is a special IP address which is used to refer to any available interface on the machine. So if your machine has a loopback (lo), ethernet (eth0), Wifi (wlan0) with respective IP as 127.0.0.1
, 192.168.0.100
, 10.0.0.100
.
因此,现在在侦听传入连接时,您可以选择上述IP中的任何一个
So now while listening for incoming connection you can choose any of the above IP
gunicorn wsgi:application --workers 2 --bind 10.0.0.100:8000
这只能从您的Wifi网络访问.但是Lan网络上的其他计算机无法访问它.因此,如果您希望您的应用程序在计算机上的任何可用网络上侦听,请使用特殊的IP 0.0.0.0
.这意味着在所有网络接口上绑定
This will only be reachable from your Wifi network. But other machines on Lan network can't visit it. So if you want your app to listen on any available network on the machine you use a special IP 0.0.0.0
. This means bind on all network interfaces
gunicorn wsgi:application --workers 2 --bind 0.0.0.0:8000
现在,当您使用http://0.0.0.0
访问应用程序时,它等同于使用127.0.0.1
.因此,您的proxy_pass http://0.0.0.0:8000;
等同于proxy_pass http://127.0.0.1:8000;
Now when you access the app using http://0.0.0.0
it is equivalent to using 127.0.0.1
. So your proxy_pass http://0.0.0.0:8000;
is equivalent to proxy_pass http://127.0.0.1:8000;
因此,当您在nginx容器中运行该请求时,它将在同一容器的端口8000上传递请求,而在nginx容器中的8000上没有任何运行.因此,您需要将该请求发送到您的gunicorn容器.可以使用docker-compose
中的服务名称web
来访问.
So when you run that in nginx container, it passes on the request on port 8000 of the same container and there is nothing running on 8000 in your nginx container. So you need to send that request to the your gunicorn container. This is reachable using the service name web
in docker-compose
.
有关更多详细信息,请参见以下文章 https://docs.docker.com/compose/networking/
See the below article for more details https://docs.docker.com/compose/networking/