skip to Main Content

I try to run 3 containers: nginx and two containers with flask-uwsgi but one for staging one for live.

In docker i create network:

docker network create --attachable --subnet 1.1.1.0/29 some-network

And run containers like:

# nginx
docker run -d --rm 
       --net some-network --ip 1.1.1.2 
       -p 80:80 -p 443:443 
       --name my-nginx "$REGISTRY/$IMAGE"

# flask+uwsgi on :8080 (live)
docker run -d --rm 
      --net some-network --ip 1.1.1.3 
      -p 8080:8080 
      --name flask-live "$REGISTRY/$IMAGE"

And i have default server config with upstreams:

upstream flask_live {
    server  1.1.1.3:8080;
}

upstream flask_dev {
    server  1.1.1.4:8080;
}


server {
    listen 80;
    server_name hostname.com;
    location / {
        include uwsgi_params;
        uwsgi_pass flask_live;
    }
}

server {
    listen 80;
    server_name develop.hostname.com;

    location / {
        include uwsgi_params;
        uwsgi_pass flask_dev;
    }
}

But when i try to run third container with flask develop like:

docker run -d --rm 
      --net some-network --ip 1.1.1.4 
      -p 8080:8080 
      --name flask-live "$REGISTRY/$IMAGE"

I get error: Bind for 0.0.0.0:8080 failed: port is already allocated
I don’t understand why port allocated if i try to publish on 1.1.1.0/29 subnet
I read docker docs about networking, I google stuff but I am just blind or slow but i don’t understand how to "isolate" container or something like that.

2

Answers


  1. -p 8080:8080 is equal to -p 0.0.0.0:8080:8080 where:

    • 0.0.0.0 – address on the host to redirect from
    • first 8080 – port to redirect from
    • second 8080 – port of container (inside docker network)

    So, your error message says that you cannot bind to port 8080 of the host (not your internal docker network).

    This command allows you to access your container from host network (eg. from localhost:8080 to 8080 port of your container). Basically, it uses iptables to redirect packets from one network to another. So, when you call -p 8080:8080, it will redirect packets from port 8080 to your first container and when you call the same command for second container it fails, because port 8080 is already in use. You cannot you the single port to redirect to both containers at the same time.

    Based on your description, you don’t even need to publish ports to your flask-uwsgi containers, because you have a nginx proxy, which will allow you to access them based on host names. These ports will still be available inside your Docker network, you just won’t publish then to your host OS.

    If you still need to access your flask-uwsgi containers directly (without nginx), then you can publish them to different ports. Eg. first – -p 8081:8080, second – -p 8082:8080).

    Login or Signup to reply.
  2. The docker run -p option opens a port on the host that forwards to a port in the container. That generally means you can’t run two containers that have the same first -p port number, and that first port number also can’t conflict with a non-container process running on the host.

    Separately, Docker maintains its own networking layer. It’s useful to know that, as an implementation detail, each container happens to have its own IP address, so you can run processes in separate containers that each listen on port 8080 and they won’t conflict. You don’t need a -p option to do this.

    So: connections from outside Docker

    • Use the host’s DNS name or IP address
    • Use the first docker run -p port number (which must be unique across all containers and host processes)
    • The process inside the container must listen on the second -p port number and the special 0.0.0.0 "everywhere" IP address

    Connections between containers

    • Must be on the same docker run --net network
    • Use the other container’s docker run --name as a DNS name
    • Use the port number the destination container’s process is listening on; it also must be listening on the special 0.0.0.0 "everywhere" IP address
    • Ignore docker run -p port mappings

    Notice that neither of these cases actually needs to know the container-private IP address, and it’s not usually useful to specify these or look them up. In your example I would delete the docker network create --subnet option and the docker run --ip options.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search