1

I'm trying to configure Nginx (inside Docker container) with Node.js (outside, on host machine). The Nginx configuration uses upstream and proxy-pass directives:

upstream helloworld {
    server localhost:8080;
}

server {
    listen 443;
    ssl on;
    ssl_certificate /some/cert.crt;
    ssl_certificate_key /some/cert.key;
    location / {
        proxy_pass http://helloworld;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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 https;
    }
}

Node app listens on port 8080 of the host machine. Now, I start Nginx container

docker run \
        -d \
        -p 80:80 \
        -p 443:443 \
        -p 8080:8080 \
        -v /some/mounts:/to/some/mounts \
        --name nginx \
        nginx:alpine

What I expect is that Nginx receives connections to ports 80 and 443 and forwards them to port 8080 inside of its container, which will then be forwarded to port 8080 of the host machine to the Node app (-p 8080:8080), however it gives an error: Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use.

I've tried changing localhost to 127.0.0.1 and even to the ip-address of the host machine (172.17.0.1 produced by $ /sbin/ip route from inside of the Nginx container), but none of it seems to work. If I don't use -p 8080:8080 while starting the container it doesn't work either.

Even though 172.17.0.1 is the host machine's ip-address, I can't connect to it from within the Nginx container:

$ wget 172.17.0.1:8080
Connecting to 172.17.0.1:8080... failed: Connection refused.

Now, I know I can Dockerize my Node app and use --link argument when starting Nginx container, but it is not a solution for the moment, since it requires a lot of re-writing of the Node app.

Any help is very much appreciated.

1 Answer 1

3

I would first suggest that you move your nodejs app into a container on the same network (bridge network) as nginx. It makes it easier/more secure (isolate node behind the nginx public proxy).

Otherwise, run your nginx on the host network so that its localhost is the same as the host.

docker run \
    -d \
    -p 80:80 \
    -p 443:443 \
    -p 8080:8080 \
    -v /some/mounts:/to/some/mounts \
    --name nginx \
    --network host \
    nginx:alpine

If you're still getting a bind: address already in use, that's because more than one service is listening to that address. Use netstat or lsof (linux|osx) to figure out what process is listening to 8080.

Some extra info on network settings. https://docs.docker.com/engine/reference/run/#/network-settings

Sign up to request clarification or add additional context in comments.

4 Comments

Ok, I've tried using --network host (with and without -p 80:80 and so on, since I guess with this option port declarations are redundant). If I do $ curl https://127.0.0.1, it works, I get response from the Node app, however Nginx stopped responding to requests from outside (i.e. if I navigate to https://xxx.xxx.xxx.xxx from browser) -.- Another interesting issue is that if do $ curl https://localhost (instead of 127.0.0.1), I get the standard "Welcome to Nginx" page o.O
Your nginx.conf only listens to 443, not 80.
Also, your nginx is on the host network (localhost, loopback, etc), so it's not accessible from outside your computer. Unless you're trying something esoteric, I really suggest you follow the best practices. Run your containers in a private bridge network and only expose your nginx to the outside world.
I removed the part with port 80 for conciseness from the nginx.conf :) I'm not trying something esoteric, it's just very time-consuming to develop an app and then re-dockerize it every time I want to test it. So I thought that maybe I should dockerize Nginx, since it's not going to change and leave my Node app as-is (in order to dockerize it in the very end of the development). Thanks for the feedback!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.