Simplest nginx reverse proxy to another container on same host gives 502 Bad Gateway / connection refused

5,471

Using bridge as the magic key word, I finally started getting the search engine results I needed.

The comment on the question pointed out the issue: nginx was just forwarding requests to localhost:8080 internally within its own container, rather than the host:ports where the other docker containers are found.

I checked around and lots of people are writing the FQDNs of their proxied servers into their nginx.conf, which I didn't want to since I figured it might get overcomplicated when the build populates the configuration files for each environment.

So from Accessing host machine from within docker container and Docker docs I learnt about docker network today and implemented the following to give my dev environment a unique and unchanging host ip.

In my nginx.conf for the reverse proxy, I have proxy_pass http://myapp:8080 where myapp will be the docker container name I give the proxied app.

Then I create the user-defined bridge network:

docker network create -d bridge myapp-net

I don't yet understand why the default docker bridge network won't work.

And then I launch the containers, attaching them to the myapp-net:

docker run -p 8080:8080 --network=myapp-net --name myapp --rm myregistry:11095/myapp

docker run -p 10040:443 --network=myapp-net --name rproxy --rm myregistry:11095/myapp-rproxy

and it works.

I'm working on my Windows workstation and I figured writing the real external host FQDN into nginx.conf would require a new environment definition for each workstation, but with myapp in the conf file instead, it removes the dependency on the host name or IP.

Share:
5,471

Related videos on Youtube

Adam
Author by

Adam

My interests include Java, photos, music, financial trading, environmental issues, Open Source projects, networking, operating systems like linux (Debian/Ubuntu) and Macs and hardware. SOreadytohelp

Updated on September 18, 2022

Comments

  • Adam
    Adam over 1 year

    Totally stuck now.

    This is what I have. I build and run a simple HTML page in nginx on port 8080 (I eventually want to run a Java tomcat app when I've figured this out).

    This is on Windows 10 with Docker 17.09 and nginx 1.13

    This is the config:

    $ cat Dockerfile
    FROM nginx
    COPY nginx.conf /etc/nginx
    COPY static-html /usr/share/nginx/html
    EXPOSE 80
    

    and the config:

    $ cat nginx.conf
    
    user  nginx;
    worker_processes  1;
    
    error_log  /dev/stdout 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  /dev/stdout  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
    
        include /etc/nginx/conf.d/*.conf;
    }
    

    Run it like this:

    $ docker run -p 8080:80 --name dummy --rm dummy-nginx
    

    Responds nicely to curl:

    $ curl -i http://localhost:8080
    HTTP/1.1 200 OK
    Server: nginx/1.13.7
    Date: Thu, 30 Nov 2017 16:46:17 GMT
    Content-Type: text/html
    Content-Length: 101
    Last-Modified: Wed, 29 Nov 2017 16:24:39 GMT
    Connection: keep-alive
    ETag: "5a1edf47-65"
    Accept-Ranges: bytes
    
    <head>
      <title>oh yeah</title>
    </head>
    <body>
      <h1>Absolutely</h1>
      <p>did this work?</p>
    </body>
    

    So that all works fine. This is the same stuff for the reverse proxy which is the part that fails:

    Reverse proxy Dockerfile

    FROM nginx
    COPY nginx.conf /etc/nginx/nginx.conf
    COPY apt-proxy.conf /etc/apt/apt.conf.d
    COPY nginx_signing.key /etc/apt
    RUN apt-get update
    RUN apt-get -y install apt-utils
    RUN apt-get -y install gnupg gnupg2 gnupg1
    RUN apt-key add /etc/apt/nginx_signing.key
    RUN apt-get -y install curl
    RUN apt-get -y install net-tools
    EXPOSE 10040
    CMD ["nginx"]
    

    (I put those extra tools in there to try to help diagnose this)

    Reverse proxy nginx.conf

    daemon off;
    user  nginx;
    worker_processes  1;
    pid        /var/run/nginx.pid;
    error_log /dev/stdout debug;
    events { worker_connections 1024; }
    
    http {
        access_log /dev/stdout;
    
        upstream myapp {
            server localhost:8080;
        }
    
        server {
            listen 10040;
    
            location / {
                proxy_pass $scheme://myapp;
                proxy_redirect default;
                proxy_set_header HOST $host;
                proxy_set_header Referer $http_referer;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_set_header X-Forwarded-Proto $scheme;
            }
        }    
    }
    

    I heavily suspect the whole problem is just a minor error in there somewhere (banging head against wall).

    Command line to start up the reverse proxy

    This includes a bit of the logging with the error from nginx, and the access_log item which I also piped to /dev/stdout.

    $ docker run -p 10040:10040 --name rproxy --rm we1p202420008.cloud.registry(example).com:11095/rproxy
    2017/11/30 16:55:20 [notice] 1#1: using the "epoll" event method
    2017/11/30 16:55:20 [notice] 1#1: nginx/1.13.7
    2017/11/30 16:55:20 [notice] 1#1: built by gcc 6.3.0 20170516 (Debian 6.3.0-18)
    2017/11/30 16:55:20 [notice] 1#1: OS: Linux 4.9.49-moby
    2017/11/30 16:55:20 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
    2017/11/30 16:55:20 [notice] 1#1: start worker processes
    2017/11/30 16:55:20 [notice] 1#1: start worker process 5
    2017/11/30 16:55:25 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "localhost:10040"
    172.17.0.1 - - [30/Nov/2017:16:55:25 +0000] "GET / HTTP/1.1" 502 173 "-" "curl/7.56.1"
    2017/11/30 16:55:25 [info] 5#5: *1 client 172.17.0.1 closed keepalive connection
    

    That error is logged when I try to access the dummy website thro the r-proxy like this:

    $ curl -i http://localhost:10040
    HTTP/1.1 502 Bad Gateway
    Server: nginx/1.13.7
    Date: Thu, 30 Nov 2017 18:05:06 GMT
    Content-Type: text/html
    Content-Length: 173
    Connection: keep-alive
    
    <html>
    <head><title>502 Bad Gateway</title></head>
    <body bgcolor="white">
    <center><h1>502 Bad Gateway</h1></center>
    <hr><center>nginx/1.13.7</center>
    </body>
    </html>
    

    Now if there is nothing obvious in the config I've just posted and it really isn't just my stupidity, then there is some baffling stuff which I can't get any further with. For instance, when I run curl inside my reverse proxy instance:

    docker exec rproxy curl -i http://localhost:8080

    it gives me the corporate firewall's blocked content result:

    The website http://localhost/ that you are trying to access is currently categorised as Uncategorized URLs< and has been deemed to be potentially unsafe or unsuitable for browsing.