No. The EXPOSE instruction does not open or publish a port. It documents which port the container listens on. A port becomes reachable from outside only when you publish it at run time, for example with the p option on docker run, or with the capital P option that publishes every exposed port.
Myth versus fact
| Claim | Verdict |
|---|---|
| EXPOSE makes the service reachable from the internet | Myth |
| Leaving out EXPOSE blocks access | Myth |
| EXPOSE is metadata that tells people and tools what to publish | Fact |
| Publishing a port is a run time decision | Fact |
The Dockerfile reference says plainly that EXPOSE does not actually publish the port and works as documentation between the person who builds the image and the person who runs the container. Protocol defaults to TCP, and you can state UDP, as in EXPOSE 80/udp.
What publishing really does
When you publish a port, the engine maps a port on the host to the container port. Docker's best practices page describes EXPOSE as indicating the ports on which a container listens, and notes that users map ports at run time. So the dangerous step is the publish, not the EXPOSE line.
The capital P option is the one to watch. It publishes all exposed ports to high numbered host ports. If a base image exposes a debug or admin port you never looked at, that option will publish it too.
Where people get caught
Three habits cause most surprises.
- Copying a docker run command from a tutorial that publishes more ports than your service needs.
- Using the capital P option in scripts without reading what the image exposes.
- Assuming a Compose file is private because the Dockerfile has no EXPOSE line. Compose ports entries publish ports regardless of what the Dockerfile says.
You can read what an image declares with docker inspect and look at the exposed ports field. Do that for every third party image before you run it with broad publishing.
A safer habit
State only the ports your service really listens on. Publish them explicitly, one at a time. On a developer laptop, bind the host side to the loopback address so a database or admin UI is not reachable from the local network. In production, put the container behind a load balancer or ingress and keep direct host publishing off.
Also review image scans for listening services you did not expect. A scanner that reads the image will not tell you what is reachable from the internet, because reachability depends on how you run and route it. Treat network exposure as its own check next to your scan results.
Quick check
Should I still write EXPOSE if it does nothing?
Yes. It documents the port for people and tools and makes the capital P option behave as expected. Just do not treat it as a firewall rule.
How do I see what ports an image declares?
Run docker inspect on the image and read the exposed ports field. That shows what the image author documented.
Safeguard
Safeguard does SBOM and dependency scanning, and its policies and gates can run in CI so a bad image does not reach production. You can try a free scan before deciding anything.
Sources
Last reviewed: 19 October 2026.