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;
}
}
and my docker-compose.yml
file is as follows:
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:
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"
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.
Thank you in advance.
Change your proxy_pass from
to
Your nginx needs to forward to request the web container
Edit-1: Explanation
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 as127.0.0.1
,192.168.0.100
,10.0.0.100
.So now while listening for incoming connection you can choose any of the above IP
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 interfacesNow when you access the app using
http://0.0.0.0
it is equivalent to using127.0.0.1
. So yourproxy_pass http://0.0.0.0:8000;
is equivalent toproxy_pass http://127.0.0.1:8000;
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
indocker-compose
.See the below article for more details https://docs.docker.com/compose/networking/