I would like to create two services, both of them having their own nginx. I would like to use third nginx as a reverse proxy to these two but I got
502 Bad Gateway
when I request
http://127.0.0.1:8080/
http://127.0.0.1:8080/one
http://127.0.0.1:8080/two
accessing:
http://127.0.0.1:8081
http://127.0.0.1:8082
works ok
I have this docker-compose.yml
version: "3.3"
services:
nginx-one:
image: nginx:1.17.8
ports:
- "8081:80"
networks:
- frontend
- backend
volumes:
- ./nginx-one/html:/usr/share/nginx/html
nginx-two:
image: nginx:1.17.8
ports:
- "8082:80"
networks:
- frontend
- backend
volumes:
- ./nginx-two/html:/usr/share/nginx/html
nginx-reverse-proxy:
image: nginx:1.17.8
ports:
- "8080:80"
networks:
- frontend
- backend
volumes:
- ./nginx-reverse-proxy/html:/usr/share/nginx/html
- ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d
debian-network:
image: cslev/debian_networking
stdin_open: true # docker run -i
tty: true # docker run -t
networks:
- frontend
- backend
networks:
frontend:
internal: false
backend:
internal: true
and dir structure
.
├── docker-compose.yml
├── nginx-one
│ └── html
│ └── index.html
├── nginx-reverse-proxy
│ ├── conf.d
│ │ └── default.conf
│ └── html
│ └── index.html
├── nginx-two
└── html
└── index.html
nginx.conf content
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
and
conf.d/default.conf
server {
listen 80;
location /one {
proxy_pass http://127.0.0.1:8081/;
}
location /two {
proxy_pass http://127.0.0.1:8082/;
}
}
When I comment this line of docker-compose.yml
# ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d
so conf.d/default.conf
is not used, and I request from the host's browser:
http://127.0.0.1:8080/
it gives a proper response from the nginx-reverse-proxy itself but obviously
http://127.0.0.1:8080/one
http://127.0.0.1:8080/two
don't provide any response from
http://127.0.0.1:8081
http://127.0.0.1:8082
but 404 instead.
docker ps output:
IMAGE COMMAND CREATED STATUS PORTS NAMES
cslev/debian_networking "bash" 25 minutes ago Up 3 minutes nginxproblem_debian-network_1
nginx:1.17.8 "nginx -g 'daemon of…" 47 minutes ago Up 3 minutes 0.0.0.0:8080->80/tcp nginxproblem_nginx-reverse-proxy_1
nginx:1.17.8 "nginx -g 'daemon of…" 14 hours ago Up 3 minutes 0.0.0.0:8082->80/tcp nginxproblem_nginx-two_1
nginx:1.17.8 "nginx -g 'daemon of…" 14 hours ago Up 3 minutes 0.0.0.0:8081->80/tcp nginxproblem_nginx-one_1
runnnig this script:
#!/bin/sh
docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8080
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-reverse-proxy_1:8080
docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8080/one
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-reverse-proxy_1:8080/one
docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8080/two
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-reverse-proxy_1:8080/two
docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8081
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-one_1:8080
docker exec nginxproblem_debian-network_1 curl -sS 127.0.0.1:8082
docker exec nginxproblem_debian-network_1 curl -sS nginxproblem_nginx-two_1:8082
gives:
curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-reverse-proxy_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-reverse-proxy_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-reverse-proxy_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8081: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-one_1 port 8080: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8082: Connection refused
curl: (7) Failed to connect to nginxproblem_nginx-two_1 port 8082: Connection refused
when - ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d
is not commented,
and the same output when - ./nginx-reverse-proxy/conf.d:/etc/nginx/conf.d
is commented in contrary to accessing ip addresses from the browser.
Unless you have host networking enabled, 127.0.0.1
is pointing to the container itself. You can refer to the other two containers from inside a container in the same network by the service name, e.g. nginx-one
or nginx-two
.
You're also mapping the container port 80 to port 8080/8081/8082 on the host machine. This however does nothing for communication between containers in the same network. Check the docs:
By default, when you create or run a container using docker create or docker run, it does not publish any of its ports to the outside world. To make a port available to services outside of Docker, or to Docker containers which are not connected to the container’s network, use the --publish or -p flag. This creates a firewall rule which maps a container port to a port on the Docker host to the outside world.
So, try changing http://127.0.0.1:8081/;
to http://nginx-one/;
and it should work.