A flat stack
Both services share one network, and one port is bound to every interface
services:
web:
image: nginx
ports:
- "8080:80"
db:
image: postgres:16
expose:
- "5432"Work out who can reach whom. Publishing and exposing are about the host; what containers can reach each other on is decided entirely by which networks they share.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press View. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
Both services share one network, and one port is bound to every interface
services:
web:
image: nginx
ports:
- "8080:80"
db:
image: postgres:16
expose:
- "5432"The frontend genuinely cannot reach the database, and the database has no egress
services:
web:
image: nginx
networks: [front]
db:
image: postgres:16
networks: [back]
networks:
front: {}
back:
internal: trueThese are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
Publishing is about the host. Every other container on the same network reaches it on any port it listens on.
Instead:Put it on a separate network that only its consumers join.
It is documentation. It neither opens a port on the host nor limits what containers can reach.
Instead:Use networks for isolation and ports for host access.
It binds every interface and reaches past the host firewall, so on a public host it is a database on the internet.
Instead:Write "127.0.0.1:5432:5432".
Compose puts them all on one network unless told otherwise, and there is no filtering on it. Publishing a port does not open it to other containers, and not publishing does not close it.
It is documentation inherited from the Dockerfile's EXPOSE. People assume it opens a port to the host, which it does not, and separately assume it limits what other containers can reach, which it also does not.
And Docker's forwarding rules sit in front of the host firewall, so it answers from the network even under a default-deny policy. Writing "127.0.0.1:5432:5432" publishes to the loopback only, which is the correct form for anything behind a reverse proxy on the same host.
A frontend network and a backend network, with the database only on the backend one, means the frontend genuinely cannot open a connection to the database. That is a property of the network layout rather than of the port configuration.
A container on an internal network alone cannot reach the internet at all. That is a real control for a database, and it also breaks anything expecting to fetch updates or call an external API, usually at the least convenient moment.
Whether the applications actually listen where they say. It reads the compose file, in your browser, and reaches nothing.