Docker EXPOSE vs Ports Explainer
Understand container port exposure, host publishing (-p), interface binding, and firewall implications — entirely on this device.
EXPOSE 8080/tcp
-p 0.0.0.0:80:8080/tcp
ports: - "0.0.0.0:80:8080"
Do it offline:$
How to use it
- Select the internal container listening port and optional host forwarded port.
- Toggle between publishing to the host (-p) and keeping the port purely internal.
- Choose your interface binding: 0.0.0.0 (public access) or 127.0.0.1 (local host loopback only).
- Inspect the reachability report for host access, inter-container communication, and public internet exposure.
- Review the resulting Dockerfile, Docker CLI command, and docker-compose.yaml snippets.
Understand and simulate the architectural differences between Dockerfile EXPOSE directives and host port publishing flags (-p / ports in Compose) with live firewall security advisories.
How it works
EXPOSE in a Dockerfile functions merely as documentation and metadata between the image author and container operators. It does NOT configure host firewall iptables rules or publish ports to the outside world.
The -p / --publish flag (or ports in docker-compose.yaml) instructs the Docker daemon to write NAT iptables port forwarding rules, routing incoming host packets to the container network namespace.
Containers on the same user-defined bridge network can communicate with each other on any listening port without needing EXPOSE or -p directives.
By default, Docker's iptables manipulation can bypass host UFW rules when binding to 0.0.0.0. Binding sensitive services to 127.0.0.1 shields them from external exposure.
Examples
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Common errors
FAQ
Does EXPOSE 80 actually make port 80 available on my host server?
No! EXPOSE only serves as documentation and a hint to orchestrators. To reach the port from your host machine or the internet, you must explicitly publish it using '-p 80:80' or '--publish'.
Why should internal databases (PostgreSQL, Redis) never be published to 0.0.0.0?
Publishing to 0.0.0.0 opens the database port to anyone who can reach the host IP address. On Linux, Docker often bypasses standard UFW firewall rules. Keep databases internal to Docker networks or bind them exclusively to 127.0.0.1.
What does the -P (capital P) flag do in 'docker run -P'?
The uppercase '-P' flag tells Docker to publish ALL ports listed in the Dockerfile EXPOSE instruction to random high-numbered ephemeral ports on the host (typically in the 32768-60999 range).