Docker cannot bind the host port because something already holds it: another container, a host service, or a stuck docker-proxy process.

Common causes

  • Another container publishes the same host port, often after switching Compose projects.
  • A host service uses the port, such as nginx, Apache or Pi-hole.
  • An old container is still running because docker compose down was never executed.
  • A container uses network_mode: host and also declares port mappings.
  • A docker-proxy process from a removed container still holds the port.

How to check it

Who listens on the port?

ss -lntp | grep ':80 ' 

Which container publishes it?

docker ps --format 'table {{.Names}}\t{{.Ports}}' | grep ':80' 

All ports including stopped containers

docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' 

What actually helps

  1. Find and stop the container with docker stop NAME, then run docker compose up -d again.
  2. Identify the host service and either stop it or move the container to another port, for example 8080:80.
  3. With several Compose projects, assign ports deliberately instead of mapping 80 and 443 twice.

FAQ

Can two containers both use port 80?

Not directly. Only one holds the host port. Put a reverse proxy in front and use different internal ports.

The port is taken but docker ps is empty.

Then a host process holds it. ss -lntp shows the PID and program.

Full page with every command and the German/Italian version: daniele-michelin.com/en/errors/docker-port-already-allocated/

First published at daniele-michelin.com. The error lexicon covers HTTP, DNS, TLS, mail, database, PHP, nginx, systemd and Nextcloud, in German, English and Italian.