How to manage Docker container ports with the port, expose and publish commands.
The Docker commands related to ports specify how to connect Docker containers over Docker networks and to host machines. This article will explain the difference between the commands and how you can use them effectively in your Dockerfile and Docker Compose file.
To view a list of the ports defined on a container, you can use the
docker port command.
docker port CONTAINER [PRIVATE_PORT[/PROTOCOL]]
It lists all port mappings or a specific mapping for a Docker container.
docker port test_container 7890/tcp -> 0.0.0.0:4321 9876/tcp -> 0.0.0.0:1234 docker port test_container 7890/tcp 0.0.0.0:4321
See more in the Docker docs: Docker command line reference - port.
Dockerfile expose vs publish
When writing your Dockerfiles, the instruction EXPOSE tells Docker the running container listens on specific network ports. This acts as a kind of port mapping documentation that can then be used when publishing the ports.
EXPOSE <port> [<port>/<protocol>...]
You can also specify this within a docker run command, such as:
docker run --expose=1234 my_app
But EXPOSE will not allow communication via the defined ports to containers outside of the same network or to the host machine. To allow this to happen you need to publish the ports.
See more in the Docker docs: Dockerfile reference - expose.
Publish ports and map them to the host
There are several flags you can use when using the docker run command to publish a container’s ports outside of the container’s network and map them the host machine’s ports. These are the flags -p and -P, and they differ in terms of whether you want to publish one or all ports.
To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports. — Docker docs: EXPOSE
docker run -p 80:80/tcp -p 80:80/udp my_app
In the above example, the first number following the
-p flag is the host port, and the second is the container port.
To publish all the ports you define in your Dockerfile with EXPOSE and bind them to the host machine, you can use the
docker run -P my_app
Docker Compose expose vs ports
Like EXPOSE in a Dockerfile, this instruction is used to expose ports without publishing them to the host machine — they’ll only be accessible to linked services on the same network.
expose: - "3000" - "8000"
See more about expose in the Docker docs: Docker Compose files - expose.
This is used to publish ports to a host. You can either use a short syntax, or give a more detailed configuration.
Either specify both ports (
HOST:CONTAINER), or just the container port (an ephemeral host port is chosen).
ports: - "3000" - "8000:8000/tcp" - "127.0.0.1:8001:8001"
The long form syntax allows the configuration of additional fields that can’t be expressed in the short form.
- target: the port inside the container
- published: the publicly exposed port
- protocol: the port protocol (tcp or udp)
- mode: host for publishing a host port on each node, or ingress for a swarm mode port to be load balanced.
ports: - target: 80 published: 8080 protocol: tcp mode: host
See more in the Docker docs: Docker Compose file - ports.
Find out more
ports commands can help you master connecting to containers within and outside a Docker network. Check out the Docker’s docs pages and my other Docker posts for more details.