Search code examples
dockernginx

How do I open another port in a docker nginx container (only in the container; so, NOT publishing which is the -p flag)?


On my local laptop.

I'm learning about ports and Docker and am having problems using different ports in nginx. I would like to start an nginx container and specify a port, open the container shell, and test the web server with curl on the port I specified. In Docker, I've tried to use --expose <different_port_here> and also tried -e NGINX_PORT=<different_port_here> when creating the container but none of them worked. Only the default port 80 works.

Anybody know how I can open a different port within my container? I DON'T want to publish and forward the port outside the container.

Attempt 1

The first thing I tried was to use --expose <different_port_here>

docker run --name my-nginx-container-w-expose -d --expose 100 nginx:stable-perl

When I do docker ps it shows port 100/tcp and 80/tcp so I thought that port 100 would also be open now.

Then I go into the shell and try curl with the following commands

docker exec -it my-nginx-container-w-expose /bin/bash

curl http://localhost:<different_port_here>

Return the following below:

curl: (7) Failed to connect to localhost port 100: Connection refused

Attempt 2

The 2nd thing I tried was to use -e NGINX_PORT=<different_port_here>

docker run --name my-nginx-container-w-env-variable -d nginx:stable-perl

When I do docker ps it does NOT shows port 100/tcp but shows 80/tcp.

Then I go into the shell and try curl with the following commands

docker exec -it my-nginx-container-w-env-variable /bin/bash

curl http://localhost:<different_port_here>

curl: (7) Failed to connect to localhost port 100: Connection refused

The only port I can use is 80

The only port which curl works with when in the container is 80.

curl http://localhost:80

Return

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Solution

  • Your nginx configuration tells nginx which ports to listen on. If you have a file called nginx.conf like this

    server {
            listen 80;
            location / {
                    index index.html;
                    root /usr/share/nginx/site1;
                    try_files $uri $uri/ $uri.html =404;
            }
    }
    
    server {
            listen 100;
            location / {
                    index index.html;
                    root /usr/share/nginx/site2;
                    try_files $uri $uri/ $uri.html =404;
            }
    }
    

    nginx will listen on port 80 and port 100 and serve different content on the two ports.

    If you then make a Dockerfile like this

    FROM nginx
    COPY nginx.conf /etc/nginx/conf.d/default.conf
    RUN mkdir -p /usr/share/nginx/site1 && \
        mkdir -p /usr/share/nginx/site2 && \
        echo Site1 > /usr/share/nginx/site1/index.html && \
        echo Site2 > /usr/share/nginx/site2/index.html
    

    You can build, run and test it like this

    docker build -t test .
    docker run -d --rm -p 8080:80 -p 8100:100 test
    curl localhost:8080
    curl localhost:8100
    

    The 2 curl commands then return 'Site1' and 'Site2'

    If you don't want to expose the ports, you can just leave out the mapping of the ports on the docker run command. Nginx will still listen on the ports in the container (80 and 100).