51

I'm trying to have a docker container with nginx work as reverse proxy to other docker containers and I keep getting "Bad Gateway" on locations other other than the base location '/'.

I have the following server block:

server {

  listen 80;

  location / {
    proxy_pass "http://game2048:8080";
  }

  location /game {
    proxy_pass "http://game:9999";
  }

}

It works for http://localhost but not for http://localhost/game which gives "Bad Gateway" in the browser and this on the nginx container:

[error] 7#7: *6 connect() failed (111: Connection refused) 
while connecting to upstream, client: 172.17.0.1, server: , 
request: "GET /game HTTP/1.1", upstream: "http://172.17.0.4:9999/game", 
host: "localhost"

I use the official nginx docker image and put my own configuration on it. You can test it and see all details here: https://github.com/jollege/ngprox1

Any ideas what goes wrong?

NB: I have set local hostname entries on docker host to match those names:

127.0.1.1       game2048
127.0.1.1       game
jollege
  • 1,019
  • 1
  • 9
  • 12
  • Now that I post it, I see that the path "game" is passed on to the upstream server, that part should not be passed on. Any ideas how to handle that? Btw, in the scenario I want to use it for, I want it to proxy to different services based on the incoming server name / http header. – jollege Nov 03 '17 at 08:36
  • I was using the wrong port. – Abdus Oct 22 '21 at 07:28

9 Answers9

34

I fixed it! I set the server name in different server blocks in nginx config. Remember to use docker port, not host port.

server {

  listen 80;
  server_name game2048;

  location / {
    proxy_pass "http://game2048:8080";
  }

}

server {

  listen 80;
  server_name game;

  location / {
    # Remember to refer to docker port, not host port
    # which is 9999 in this case:
    proxy_pass "http://game:8080";
  }

}

The github repo has been updated to reflect the fix, the old readme file is there under ./README.old01.md.

Typical that I find the answer when I carefully phrase the question to others. Do you know that feeling?

jollege
  • 1,019
  • 1
  • 9
  • 12
  • 29
    Stackoverflow is great for [rubber duck debugging](https://en.wikipedia.org/wiki/Rubber_duck_debugging) :) – samprog Nov 03 '17 at 09:54
  • 6
    Indeed! I hadn't heard that term before - but man, do I know the concept! – jollege Nov 03 '17 at 10:18
  • 4
    "Remember to use docker port, not host port." Saved me. Thanks. – Alex K Jan 17 '18 at 03:46
  • lol guys...that valid for me too, I know what's rubber duck debugging :-D – funder7 Dec 09 '20 at 01:13
  • REMEMBER TO USE DOCKER PORT, NOT THE HOST PORT. That's the point. I wasted hours because of using a bad port number. Thanks! – Tayyebi Feb 26 '23 at 17:47
  • Sorry I'm confused you said to use port 9999 in the comment but still use 8080 in the proxy_pass line? – Amon Sep 01 '23 at 21:25
  • Sorry @Amon, it's nearly 6 years ago, I can't remember. I know that I made it work as described above. I don't work actively with my own docker containers anymore (I use other people's containers). – jollege Sep 02 '23 at 04:57
10

I had the same "502 Bad Gateway" error, but the solution was to tune proxy_buffer_size following this post instructions:

proxy_buffering off;
proxy_buffer_size 16k;
proxy_busy_buffers_size 24k;
proxy_buffers 64 4k;
Washington Guedes
  • 4,254
  • 3
  • 30
  • 56
8

See the nginx error log

sudo tail -n 100 /var/log/nginx/error.log

If you see Permission denied error in the log like below -

2022/03/28 03:51:09 [crit] 1140954#0: *141 connect() to xxx.xxx.68.xx:8080 failed (13: Permission denied) while connecting to upstream, client: xxx.xx.xxx.25, server: www.example.com

See whether the value of httpd_can_network_connect is enabled or not by running the command: sudo getsebool -a | grep httpd

If you see the value of httpd_can_network_connect is off then this is the cause of your issue.

Solution: set the value of httpd_can_network_connect is on by run the command sudo setsebool httpd_can_network_connect on -P

Hope it will resolve your problem.

Towhidul Islam Tuhin
  • 1,051
  • 13
  • 10
3

For me helped this line of code proxy_set_header Host $http_host;

location / {
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header Host $http_host;
   proxy_set_header X-NginX-Proxy true;

   proxy_redirect off;
   proxy_pass http://myserver;
}
3

I had the same error, but for a web application that was just not serving at the IP and port mentioned in the config.

So say you have this:

location /game {
    proxy_pass "http://game:9999";
}

Then make sure the web application that you expect at http://game:9999 is really serving from within a docker container named 'game' and the code is set to serve the app at port 9999.

Sander Vanden Hautte
  • 2,138
  • 3
  • 22
  • 36
2

In my case, after 4 hours, only I missed put the port with semanage command.

 location / {
            proxy_pass http://A.B.C.D:8090/test;
  }

The solution was add 8090 port and works.

semanage port -a -t http_port_t  -p tcp 8090
Hernaldo Gonzalez
  • 1,977
  • 1
  • 21
  • 32
0

You have to declare an external network if the container you are pointing to is defined in another docker-compose.yml file:

version: "3"

services:
  webserver:
    image: nginx:1.17.4-alpine
    container_name: ${PROJECT_NAME}-webserver
    depends_on:
      - drupal
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - ./docroot:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - internal
      - my-passwords

networks:
  my-passwords:
    external: true
    name: my-passwords_default

nginx.conf:

server {
    listen          80;
    server_name     test2.com www.test2.com;
    location / {
        proxy_pass  http://my-passwords:3000/;
    }
}
Achraf JEDAY
  • 1,936
  • 5
  • 24
  • 33
0

You may need to telnet on the upstream machine to check to wither it's connected: tracing the /var/log/nginx/error.log would help.

0

Docker networking. The proxy_pass needs to use the Docker service name (as defined in your compose.yaml file, and not localhost or 127.0.0.1 or 0.0.0.0.

Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91