Agent Wranglers

Required

Publish only the ports visitors use

Publish a container port on all host addresses only when visitors must reach it. Bind every other published port to 127.0.0.1.

Risk if broken

Data leaked or lost

How to do it

Docker publishes ports on every host address by default. Its own rules route that traffic before a host firewall such as ufw sees it. So a database port published for a quick test is open to the internet, whatever the host firewall says. Containers on a shared network reach each other without any published port. Write 127.0.0.1:5432:5432 when only the host needs the port. Run Docker Engine 28 or later, because older releases let machines on the same local network reach ports bound to localhost. Close the rest in the cloud firewall as Deny all traffic unless a rule allows it says.

Examples

Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

YAML example

services:
  proxy:
    ports: ["80:80", "443:443"]
  db:
    image: postgres:17.11-alpine
    ports: ["127.0.0.1:5432:5432"]

Shell example

docker run -p 127.0.0.1:8080:80 -p '[::1]:8080:80' shop

How to check

docker ps --format '{{.Names}} {{.Ports}}' shows 0.0.0.0 or [::] only on the proxy's ports 80 and 443. A port scan from outside the host finds no other open port.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/operations/containers/published-ports">Agent Wranglers operations playbook</a>. In code you write, add a comment next to it with the same link.