How does publishing ports work (-p vs -P vs EXPOSE)?
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
-p HOST:CONTAINER forwards host traffic into the container's listening port (e.g. -p 8080:80); it binds all interfaces by default, prefix 127.0.0.1: to keep it local. -p 80 picks an ephemeral host port, -P publishes every EXPOSEd port that way. EXPOSE in the image only documents intent — nothing is reachable until published.
Detailed explanation
Containers are network-isolated: the app listens on its container port (welcome-to-docker on 80), unreachable until you punch a forwarding rule at create time. Syntax docker run -d -p HOST_PORT:CONTAINER_PORT nginx maps host 8080 → container 80, so http://localhost:8080 works; the Compose equivalent is ports: ["8080:80"]. Security default: published ports listen on 0.0.0.0/:: — anyone reaching your machine reaches the app — so bind databases/sensitive ports to loopback with -p 127.0.0.1:8080:80 (full form HOST_IP:HOST_PORT:CONTAINER_PORT). Variants: omit the host port (docker run -p 80 nginx) and Docker chooses an ephemeral port shown in docker ps (e.g. 0.0.0.0:54772->80/tcp); use -P/--publish-all to auto-publish every EXPOSEd port to ephemeral ports (handy against dev port conflicts). EXPOSE is metadata set at build time — required for -P to have something to publish, but publishing is what actually opens access.
Official docs:Docker docs: Publishing and exposing ports
Example
docker run -d -p 8080:80 docker/welcome-to-docker # host 8080 → container 80
docker run -d -p 127.0.0.1:8080:80 nginx # loopback only (safer for local dev)
docker run -p 80 nginx # ephemeral host port → check `docker ps`
docker run -P nginx # publish ALL exposed ports
# compose.yaml equivalent:
# services:
# app:
# image: docker/welcome-to-docker
# ports: ["127.0.0.1:8080:80"]Interview tip
State the isolation premise first ('no published port, no access'), then the triple — explicit -p, ephemeral, -P — and finish with the loopback hardening tip.
Common mistakes
- Believing EXPOSE alone makes a port reachable.
- Publishing databases on 0.0.0.0 in dev and exposing them to the network.