Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
468 views
in Technique[技术] by (71.8m points)

docker - nginx reverse proxy to other nginx 502 bad gateway

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.

question from:https://stackoverflow.com/questions/65907904/nginx-reverse-proxy-to-other-nginx-502-bad-gateway

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...