Ports & networking basics
Containers are isolated by default. Publishing a port is how you deliberately open one door.
key idea / Docker itselfcontainer / good pathhost / watch outproblem / blockedneutral
The wall around a container
A request from your browser only gets in if you publish the port.
Reading -p
Many containers, one inner port
Port numbers inside and outside are separate namespaces.
EXPOSE versus -p
The localhost trap
Try it yourself
-
Step 1 · No published port
Nginx is running, and the host still has nothing on port 8080.
$ docker run -d --name quiet --rm nginx:1.27 $ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080 000 -
Step 2 · Publish host 8080 to container 80
$ docker stop quiet $ docker run -d --name web --rm -p 8080:80 nginx:1.27 $ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080 200 $ docker port web 80/tcp -> 0.0.0.0:8080 -
Step 3 · A second container can also listen on 80
Inside each container the process uses port 80. On the host the ports are 8080 and 8081.
$ docker run -d --name web2 --rm -p 8081:80 nginx:1.27 $ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8081 200 $ docker stop web web2
Recap
-p host:containerforwards a host port into a container port.- Several containers can listen on the same inner port if their host ports differ.
EXPOSEis documentation. It does not publish anything.localhostinside a container is the container, not your laptop.
Quick check
Your app in a container calls
localhost:5432 for Postgres running on your laptop, and it fails. Why?Show answer
localhost is the container itself, and nothing listens there. Use host.docker.internal, or put the database in a container on the same network and call it by name.