Ports and Networking
Containers get their own private network. Nothing gets in or out unless you say so — which is great for security and confusing the first time your web app doesn't answer.
Publishing ports: -p
docker run -d --name web -p 8080:80 nginx
-p HOST:CONTAINER — traffic to port 8080 on your machine goes to
port 80 in the container. The order is host first, container
second. Mnemonic: it reads like the path a request travels, from
the outside in.
Check: http://localhost:8080 shows nginx. Without -p, the
container's port 80 exists but is unreachable from your machine —
the #1 "why isn't my app loading?" answer.
docker run -d -p 127.0.0.1:8080:80 nginx # only reachable from this machine
docker run -d -P nginx # -P: publish all EXPOSEd ports on random host ports
Binding to 127.0.0.1 keeps a dev server off your LAN. Plain -p
8080:80 listens on all interfaces — fine at home, think twice on a
public server.
Container-to-container: use names
Containers on the same network reach each other by container name, which Docker resolves like DNS:
docker network create appnet
docker run -d --name db --network appnet postgres:16
docker run -d --name api --network appnet myapp:1.0
Inside api, the database is at hostname db, port 5432. No IP
addresses to memorize, no -p needed between containers — -p is
only for traffic crossing into/out of the host.
Check (verified):
docker network ls
NETWORK ID NAME DRIVER
...
(Docker creates a bridge network by default; user-created networks
like appnet get DNS between containers, the default bridge
doesn't — another reason to make your own.)
The three network modes you'll meet
| Mode | What it does | When |
|---|---|---|
bridge (default) |
Private network, -p to expose |
The normal case |
host |
Container shares the host's network directly | Max performance, no isolation |
none |
No networking at all | Locked-down batch jobs |
docker run --network host myapp:1.0 # skips port mapping entirely
Debugging connectivity
Symptom → check:
- "Connection refused" on localhost → container isn't listening
there, or you forgot
-p.docker psshows published ports underPORTS. - Container can't reach another by name → are they on the same
user-created network? (
docker network inspect appnet) - Worked yesterday, broken today → container got recreated with a new IP and something hardcoded the old one. Use names, not IPs.
Next: Docker Compose