Difference Between Expose and Ports in Docker

Isaac Tony Mar 29, 2022
  1. the EXPOSE DockerFile Instruction in Docker
  2. the Docker Compose Ports
Difference Between Expose and Ports in Docker

In Docker, after we created a container using the docker create or the docker run, we may want our container to interact with outside services or other external containers. We need to make ports available to the outside world to achieve this.

In this article, we will introduce two significant ways that we can use to expose ports in Docker. We will also discuss how we can map the container port to a host port and the differences in the methods.

the EXPOSE DockerFile Instruction in Docker

A docker file is simply a text file that specifies instructions to assemble an image using the docker build command. Among these is the EXPOSE instruction.

The EXPOSE instruction is used to inform Docker that the container we are building should listen on a particular network port at runtime. However, note that this instruction is merely a reference point and does not map the container port to the host port.

Syntax:

EXPOSE <port>/<protocol>

We don’t have to specify the protocol since Docker can use the default TCP protocol. However, we can provide other protocols, such as the UDP protocol.

The Docker will use the default TCP protocol since the protocol is not specified in the Nginx official docker file.

COPY docker-entrypoint.sh /
COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
COPY 30-tune-worker-processes.sh /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE 80
STOPSIGNAL SIGQUIT
CMD ["nginx", "-g", "daemon off;"]

Suppose we pull the official Nginx image from the Docker registry, create a container, and run the container. In that case, we can quickly determine some helpful information from the container, such as the port number and the protocol used.

~/isaac$ docker ps -a

Output:

CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
99edfdea0443   nginx     "/docker-entrypoint.…"   3 minutes ago   Up 2 minutes   80/tcp    nice_volhard

The output above shows that the Nginx container runs on port 80 as stated in the Dockerfile and the TCP protocol.

Alternatively, we can also expose a port at runtime using the --expose tag when creating the container, as shown below.

docker run --expose 80 nginx

Now, bind this port to the host port number. We need to use the uppercase -P tag or the lowercase -p tag.

Although we can achieve the results with either, these tags have significant differences.

The upper case -P tag, when used at runtime, allows us to bind all exposed tags to random ports on the host. This allows us to avoid conflict in ports.

$ docker run -d -P nginx
006b88a06e51eac45895f13b33a89221676029e8fa654aaaccc79b81f74efb4d

Code:

isaac$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS         PORTS                   NAMES
006b88a06e51   nginx     "/docker-entrypoint.…"   27 seconds ago   Up 6 seconds   0.0.0.0:49153->80/tcp   angry_babbage

We can also publish a container to a specific port on the host by using the small case -p tag.

the Docker Compose Ports

Docker-compose is a utility tool that allows us to run multi-container applications on Docker.

Under the docker-compose.yml file, we can specify how our containers are configured among other files, such as the services, version of the file, volumes used, and networks that connect the services.

Like we specified port numbers in the Dockerfile, we also need to specify port numbers in the docker-compose.yml file. We can do this using the expose or ports instruction.

rabbitmq:
   image: rabbitmq
   expose: 
        - 3000
        - 5000

The expose instruction allows us to expose ports without publishing them or binding them to the host ports, i.e., ports are not exposed to host machines, only exposed to other services.

On the other hand, the ports instruction allows us to specify both host and container port numbers. Besides, these ports will be shared among other services and exposed to the host machine to a random or given port.

rabbitmq:
   image: rabbitmq
   ports: 
        - "8000:80"
        - "5000: 70"
Author: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.

LinkedIn