peez80
peez80

Reputation: 1643

docker-compose dynamic port allocation and retrieve the port

I'm implementing some tests that start docker containers via a docker-compose.yml. On the CI some times the ports that are defined in the docker-compose.yml are used currently which causes the tests to fail.

Therefore I have two questions:

  1. Is it possible to completely dynamically assign a port forwarding in docker-compose?

  2. Is there a way in the docker-compose cli to determine the port used by a specific service?

This would be the most beautiful solution in my opinion - otherwise I will need to experiment with environment variables etc.

Upvotes: 19

Views: 16128

Answers (1)

ewilan
ewilan

Reputation: 716

I think the answer is yes to your first question. I'll address the second question after I answer the first. I'm assuming that when you ask about port forwarding you are referring to Docker port publishing so that an internal port is forwarded to a port accessible from the host? If so, this answer should give you what you're looking for. I'll demonstrate how this works using an Apache Tomcat image. I'll start with Docker run, but will also show the docker-compose equivalent.

From a terminal, start Tomcat using a dynamically published port:

foo@bar:~$ docker run -dit -p 8080 --name tc01 tomcat:8-slim

Notice that only the Tomcat internal port is specified for the -p parameter.

List the port dynamically allocated to this container:

foo@bar:~$ docker port tc01
8080/tcp -> 0.0.0.0:32773

In this case, port 32773 is the dynamically published port so from my host, I can browse to http://localhost:32773 to show the Apache Tomcat home page.

If I create another container named tc02 running Tomcat while the first container (named tc01) is running:

foo@bar:~$ docker run -dit -p 8080 --name tc02 tomcat:8-slim

another port will be dynamically allocated:

foo@bar:~$ docker port tc02
8080/tcp -> 0.0.0.0:32774

In this case, visiting http://localhost:32774 will render the Apache Tomcat home page.

To do a similar thing in docker-compose, here's a simple docker-compose.yml that will dynamically allocate a port to container tc03:

version: '3.7'

services:
  tomcat:
    image: tomcat:8-slim

    ports:
      - "8080"

    container_name: tc03 

Create the container using docker-compose:

foo@bar:~$ docker-compose up -d

another port will be dynamically allocated:

foo@bar:~$ docker port tc03
8080/tcp -> 0.0.0.0:32775

In this case, visiting http://localhost:32775 will render the Apache Tomcat home page.

To answer your second question, I think you can use docker port as I've shown. So, if you name your container in your docker-compose, you can return the port value as I've shown in the examples.

If you've been creating these containers as I've outlined, you can remove them like this:

foo@bar:~$ docker rm -f tc01 tc02 tc03

Upvotes: 25

Related Questions