Containers expose its services through ports. These ports are numbers that represent a running applications inside the containers. For instance, a web server container exposes the ports 80 and/or 443 to allow other containers and the docker host to connect to this web server. Exposing a port to the outside is also known as port publishing.
Without port publishing, services running inside containers are not accessible to other containers or to the host. They are only accessible from inside the container.
The -P option (i.e., capital p or --publish-all) allows you to expose all container ports to a randomly selected ports on the docker host. The -P option is set during the creation of the container or when starting a container.
$ docker run -dit --rm --name webserver1 -P nginx:alpine
To find which port on the host is mapped to which port on the container, you may issue the following commands:
$ docker container port webserver1
$ docker container ls
Instead of mapping all container ports, a selected ports can be mapped using -p option (lowercase p) as -p <container-port>.
$ docker run -dit --rm --name webserver2 -p 80 nginx:alpine
The port specified with -p option refers to the container port.
To access a service running in a container, you need to map the corresponding port to a selected host port.
The docker run
and docker container create
commands provide the -p option (publish) to configure the mapping of a host port to a container port.
The format of the -p options is as follow: -p <host-port>:<container-port>.
$ docker run -dit --rm --name webserver3 -p 8080:80 nginx:alpine
To test that the web server is running, browse to the address http://localhost:8080 on the docker host.
To check the port mapping for a container of for all containers
$ docker container port webserver3
$ docker container ls
By default, the communication protocol is TCP. In case the protocol is UDP, this should be explicitly indicated as -p <host-port>:<container-port>/udp. To map both TCP and UDP ports, you need to provide -p option multiple times.
In addition to ports, docker allows the binding to all ip addresses or to a specific ip addresses on a host.
The following ip addresses have special meanings:
- 127.0.0.1 address represents the loopback address, which is synonym of localhost.
- 0.0.0.0 address represents all IPv4 addresses on a system knowing that a system may have multiple ip addresses.
When a port is published without an ip address, this means that the port can be accessed on all ip addresses assigned to the host. For instance, the option -p 8080:80 is equivalent to -p 0.0.0.0:8080:80.
To bind the container port 80 (web server) to port 8080 on localhost address only.
$ docker run -dit --rm --name webserver4 -p 127.0.0.1:8181:80 nginx:alpine
The EXPOSE instruction in the docker allows you to specify and document the container ports to be expose to the docker host and to other containers. The EXPOSE keyword does not map or open container ports.
# Dockerfile
EXPOSE 80
EXPOSE 443
During the creation or the start of a container generated from the image build based on the above Dockerfile, you need to specify the -p or -P options; otherwise, the port will not be bound to any host port
- Bind to specific host port: -p 8080:80
- Bind to all exposed ports to random host ports: -P
If the EXPOSE instruction is omitted in the dockerfile, the presence of the -p option replaces the EXPOSE instruction.