Expose Vs Publish - How to Use Docker Port Commands

ryanwhocodes
ryanwhocodes
Jun 29, 2018 · 3 min read

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.

Docker port

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

EXPOSE

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 -P flag.

docker run -P my_app

Docker Compose expose vs ports

When using Docker Compose to define containers, the docker-compose.yml uses the instructions expose and ports to expose and publish containers’ ports.

expose

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.

ports

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

Learning the expose, publish and 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.