Anton Egorov Anton Egorov - 1 year ago 196
Node.js Question

Docker Nginx + Node: address already in use

I'm trying to configure Nginx (inside Docker container) with Node.js (outside, on host machine). The Nginx configuration uses


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 \

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 bind: address already in use.

I've tried changing
and even to the ip-address of the host machine (
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
is the host machine's ip-address, I can't connect to it from within the Nginx container:

$ wget
Connecting to failed: Connection refused.

Now, I know I can Dockerize my Node app and use
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.

Answer Source

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 \

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.