Home > other >  Why do I keep getting (98: Address already in use) when trying to change nginx config (nginx -c)?
Why do I keep getting (98: Address already in use) when trying to change nginx config (nginx -c)?

Time:05-21

I have an nginx server running inside a docker container. I started the container with the following command:

docker run --name my-custom-nginx-container -v ~/project/nginx/conf/custom.conf:/etc/nginx/custom.conf --network host -t -d nginx

The content of my custom.conf is as follows:

events {
    worker_connections  1024;
}

http {
    server {
            listen 80;
            location / {
                proxy_pass http://127.0.0.1:8081;
      }
    }
}

Now whenever I try to change config by executing (using container shell or using docker exec directly)

nginx -c /etc/nginx/custom.conf

I always get

2022/05/19 19:53:16 [emerg] 23#23: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2022/05/19 19:53:16 [notice] 23#23: try again to bind() after 500ms
2022/05/19 19:53:16 [emerg] 23#23: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2022/05/19 19:53:16 [notice] 23#23: try again to bind() after 500ms
2022/05/19 19:53:16 [emerg] 23#23: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2022/05/19 19:53:16 [notice] 23#23: try again to bind() after 500ms
2022/05/19 19:53:16 [emerg] 23#23: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2022/05/19 19:53:16 [notice] 23#23: try again to bind() after 500ms
2022/05/19 19:53:16 [emerg] 23#23: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2022/05/19 19:53:16 [notice] 23#23: try again to bind() after 500ms
2022/05/19 19:53:16 [emerg] 23#23: still could not bind()
nginx: [emerg] still could not bind()

I've made sure no other processes are running on this port. sudo lsof -i :80 returns something of that shape:

nginx   13098            root    7u  IPv4 171510      0t0  TCP *:80 (LISTEN)
nginx   13126 systemd-resolve    7u  IPv4 171510      0t0  TCP *:80 (LISTEN)

What could be the cause of that? Could it be something docker-specific? (I'm running docker on ubuntu 22.04). I've also tried doing the same thing on nginx installed on macOS and it seemed to work.

Update

I've noticed it only does that when the previous config listened on the same port (same thing happens on local nginx installation so it's definetely not docker-specific). Hence the question comes down to:

it possible to change the config using nginx -c to one that listens on the same port as the previous one?

CodePudding user response:

You don't need docker exec here. In general, I'd suggest using it sparingly: while it's a very useful debugging tool, you don't need it in normal operation.

Here's the thing: the Docker container is the Nginx server.

Since the container is the server, if you want to stop and restart the server, you stop and delete the container and create a new one.

docker stop my-custom-nginx-container
docker rm my-custom-nginx-container
docker run --name my-custom-nginx-container -v ~/project/nginx/conf/custom.conf:/etc/nginx/custom.conf -p 80:80 -d nginx

SO questions occasionally talk about "going inside a container"; but the container is the Nginx server. So in your case, you're "going inside" the Nginx server and trying to start the same server again, which is what leads to that port conflict. Indeed, if in that docker exec shell you run ps -e you'll see the nginx process already running, and since it's the main container process, you can't stop it without causing the container to also exit.

CodePudding user response:

Ok, I've figured it out - instead of trying to change the config by calling nginx -c with different file, I'm modyfing the content of the current config file after which I'm calling nginx -s reload. (My goal was to reload the config with no downtime, hence why the answer by @David Maze did not resolve my issue).

  • Related