What the message looks like
Error response from daemon: driver failed programming external connectivity on endpoint web: Bind for 0.0.0.0:80 failed: port is already allocatedCommon 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 downwas never executed. - A container uses
network_mode: hostand also declares port mappings. - A
docker-proxyprocess from a removed container still holds the port.
Check
- 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}}' - Stuck proxy processes
ps aux | grep -i '[d]ocker-proxy'
Fix
- Find and stop the container with
docker stop NAME, then rundocker compose up -dagain. - Identify the host service and either stop it or move the container to another port, for example
8080:80. - With several Compose projects, assign ports deliberately instead of mapping 80 and 443 twice.
- Clean up old containers with
docker compose down --remove-orphans. docker restartdoes not help: the port stays taken while the other process runs.
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.