19.2.1.4 Run Port Option
A focused guide to Run Port Option, connecting core concepts with practical Docker and container operations.
The port option in docker run controls how container ports are exposed and mapped to the host machine. Containers run inside isolated network namespaces, which means their network interfaces and ports are not directly accessible from outside the container. The -p (or --publish) flag bridges this isolation by creating a rule that forwards traffic from a port on the host to a port inside the container.
Basic Syntax
docker run -p HOST_PORT:CONTAINER_PORT image
HOST_PORT is the port on the machine running Docker that external clients connect to. CONTAINER_PORT is the port the process inside the container is listening on.
docker run -d -p 8080:80 nginx:latest
This makes the nginx web server (listening on port 80 inside the container) accessible at http://localhost:8080 on the host.
Port Mapping Diagram
Specifying the Host Interface
By default, Docker binds the host port to all network interfaces (0.0.0.0), making the port accessible from any network:
docker run -d -p 8080:80 nginx:latest
# binds to 0.0.0.0:8080
To restrict access to localhost only:
docker run -d -p 127.0.0.1:8080:80 nginx:latest
To bind to a specific network interface by IP:
docker run -d -p 192.168.1.50:8080:80 nginx:latest
This is important in production environments where services should not be exposed on public interfaces.
Automatic Host Port Assignment
To let Docker select an available host port automatically:
docker run -d -p 80 nginx:latest
No host port is specified — Docker assigns a random ephemeral port. To find which port was assigned:
docker port container_name 80
Output:
0.0.0.0:32768
Or check docker ps:
PORTS
0.0.0.0:32768->80/tcp
Publishing Multiple Ports
Multiple -p flags can be used in a single docker run command:
docker run -d \
-p 8080:80 \
-p 8443:443 \
nginx:latest
Publishing All Exposed Ports
If the image has defined EXPOSE directives in its Dockerfile, the -P (uppercase) flag publishes all of them to random host ports automatically:
docker run -d -P nginx:latest
Docker maps each EXPOSEd port to a random available port on the host. This is convenient for quick testing but not for production deployments where consistent port numbers are required.
TCP vs. UDP Ports
By default, -p maps TCP ports. To map a UDP port:
docker run -d -p 53:53/udp dns-server:latest
To map both TCP and UDP for the same port:
docker run -d -p 53:53/tcp -p 53:53/udp dns-server:latest
SCTP Ports
Docker also supports SCTP (Stream Control Transmission Protocol):
docker run -d -p 9999:9999/sctp myapp:latest
Checking Port Bindings on Running Containers
docker port my-container
80/tcp -> 0.0.0.0:8080
443/tcp -> 0.0.0.0:8443
Or using inspect:
docker inspect --format '{{.NetworkSettings.Ports}}' my-container
Ports and Network Drivers
Port publishing only applies to containers using bridge networking (the default) or network address translation (NAT) drivers. When a container uses --network host, it shares the host's network stack directly and port publishing flags are ignored — the container's ports are directly accessible on the host.
# No -p needed: container process listens directly on host port 80
docker run -d --network host nginx:latest
Port Conflicts
If the specified host port is already bound by another process or container, Docker reports an error:
Error response from daemon: driver failed programming external connectivity on endpoint my-container: Bind for 0.0.0.0:8080 failed: port is already allocated
Solutions:
- Choose a different host port.
- Stop the process or container currently occupying the port.
To find what is using a port on Linux:
sudo ss -tlnp | grep 8080
On Windows:
netstat -ano | findstr :8080
Port Ranges
Docker supports mapping a range of ports:
docker run -d -p 8000-8005:8000-8005 myapp:latest
Both ranges must have the same size. Docker maps port-by-port within the range.
Security Note on Port Publishing
Every published port is an entry point to a service inside the container. Publishing ports on 0.0.0.0 exposes them to all networks the host is connected to, including public networks. Always consider:
- Using
127.0.0.1bindings for services that should only be accessed locally. - Placing containers behind a reverse proxy (nginx, Traefik, Caddy) and only publishing the proxy's port.
- Using Docker networks for container-to-container communication instead of publishing ports.