By default, Docker containers run in isolated network environments. They are assigned an internal IP address that is only accessible from the Docker host itself or other containers connected to the same virtual network.
To allow external clients (e.g., users on the internet or systems in the corporate network) to access services running inside a container, you must use Port Mapping (also known as port publishing).
When you start a container with the -p (or --publish) flag, you define a binding between a port on the host machine and a port inside the container.
Under the hood, when a port is mapped:
docker-proxy) on the host that listens on the specified host port.iptables rules in the DOCKER NAT chain) to intercept incoming traffic on that host port and forward it directly to the container’s internal IP address and port.sequenceDiagram
actor Client as External Client
participant Host as Docker Host (Port 8086)
participant Proxy as Docker Proxy / iptables
participant Container as Nginx Container (Port 80)
Client->>Host: Request http://stapp02:8086
Host->>Proxy: Intercept traffic on host port 8086
Proxy->>Container: Forward traffic to container IP on port 80
Container-->>Proxy: Return HTTP Response (200 OK)
Proxy-->>Host: Pass response
Host-->>Client: Respond to client
docker run -p <host_port>:<container_port> <image>
-p 8086:80 routes incoming host traffic on port 8086 to port 80 inside the container.By default, Docker binds the host port to all network interfaces (0.0.0.0 - any IP). You can restrict access by binding to a specific host IP address:
docker run -p 127.0.0.1:8086:80 <image>
This ensures the container is only reachable locally from the host itself, preventing external access.
By default, Docker publishes TCP ports. To map UDP ports (such as for DNS or VPN containers), append /udp to the port argument:
docker run -p 53:53/udp -p 53:53/tcp <image>
If you omit the host port, Docker will automatically map the container port to a random, unused ephemeral port on the host (typically in the range 32768 to 60999):
docker run -p 80 <image>
You can map all ports defined in the image’s EXPOSE metadata instructions to random host ports automatically using the uppercase -P flag:
docker run -d -P nginx:alpine
stapp02) (can vary in labs, e.g., stapp01, stapp02, stapp03)steve (associated with stapp02; tony for stapp01, banner for stapp03)ports_map (or custom container name)nginx:alpine808680Establish an SSH connection from the Jump Host to App Server 2:
ssh steve@stapp02
Provide the server password when prompted.
Before launching the container, verify that host port 8086 is not already bound by another service on the host:
ss -tuln | grep 8086
# or
netstat -tuln | grep 8086
If this command returns no output, the port is available.
Run the nginx:alpine container in detached mode (-d), name it ports_map, and map host port 8086 to container port 80:
docker run -d --name ports_map -p 8086:80 nginx:alpine
Note: Prepend sudo if your user is not in the docker group:
sudo docker run -d --name ports_map -p 8086:80 nginx:alpine
Ensure that the container was launched successfully and is in the Up state:
docker ps
Expected Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1fee9bf7d02e nginx:alpine "/docker-entrypoint.…" 5 seconds ago Up 5 seconds 0.0.0.0:8086->80/tcp ports_map
Confirm Nginx is actively listening on the host’s port 8086:
ss -tuln | grep 8086
Expected Output:
tcp LISTEN 0 128 0.0.0.0:8086 0.0.0.0:*
Perform an HTTP request using curl to the mapped port on localhost to verify the Nginx welcome response:
curl -I http://localhost:8086
Expected Output:
HTTP/1.1 200 OK
Server: nginx/1.25.1
Content-Type: text/html
...
Log out of the Application Server:
exit