Docker couldn't wire up the port publish when starting the container: usually the port is taken, iptables is in a bad state, or a stale endpoint from a previous run blocks the name.
ss -ltnp | grep :<port> and docker ps --format '{{.Names}} {{.Ports}}' find the holder. Publish to a different host port or stop the holder.
Leftover DOCKER-chain rules from a killed container make the proxy setup fail even when the port is free. A daemon restart (not host reboot) rebuilds the chains.
docker rm -f the old container (check docker ps -a); compose down --remove-orphans cleans the project's leftovers.
ss -ltnp | grep -E ':<port>\b' ; docker ps -a --filter name=<ct> --format '{{.Names}} {{.Status}}'
docker rm -f <ct> 2>/dev/null ; # or edit the publish: -p 8081:80
sudo systemctl restart docker # daemon restart rebuilds chains — drops other containers briefly
docker compose up -d && docker port <ct>
This error kills the container start, but compose may still leave it 'Created' — docker ps -a shows the corpse; remove before retrying. If it recurs after every host reboot with the port genuinely free, check firewalld/dockerd startup ordering on your distro.
Leftover iptables rules or a stale container endpoint: docker rm -f any matching stopped container, and if needed restart dockerd to rebuild the DOCKER chains.
With live-restore enabled, containers keep running; without it they stop and restart per their restart policy. Expect a brief blip on shared hosts — schedule it.
A production-shaped compose stack: healthchecks, resource limits, log rotation. Never debug a boot race again.
Docker Production Starter — $19 →One-time. Yours to modify. Instant download from the NinjaOps template store.