How to Fix "port is already allocated" in Docker Compose
Quick answer
The "port is already allocated" error occurs in Docker Compose when a service attempts to bind a host network port that is already in use by another running...
The "port is already allocated" error occurs in Docker Compose when a service attempts to bind a host network port that is already in use by another running container, local service, or system daemon. Host network ports (e.g., 80, 5432, 6379) can only be bound by a single process at a time on a specific network interface. Resolving this issue involves finding and terminating the conflicting process or changing the host port mapping in your Compose configuration.
The Problem
When running docker-compose up or docker compose up -d, container startup halts with a network driver binding error:
ERROR: for web Cannot start service web: driver failed programming external connectivity on endpoint web_1: Bind for 0.0.0.0:8000 failed: port is already allocated
Depending on your Docker Compose plugin version, the error message may present in this format:
Error response from daemon: driver failed programming external connectivity on endpoint app-postgres-1: Bind for 0.0.0.0:5432 failed: port is already allocated
listen tcp 0.0.0.0:5432: bind: address already in use
Why It Happens
Docker maps host ports to container ports using host routing rules (via iptables or userland proxy). The collision happens due to one of these common causes:
- Local Service Conflict: A native database or web server (e.g., local PostgreSQL on port
5432or Nginx/Apache on port80) is running on your host OS. - Orphaned Docker Containers: An earlier Docker container running in the background (or outside the current Compose stack) is already listening on the target port.
- Zombie Proxy Processes: A previously crashed Docker execution left behind an active
docker-proxyprocess holding onto the socket.
The Fix
You can solve this by either stopping the process using the target port or mapping your container to a different host port.
Step 1: Identify the process occupying the host port
Run lsof or netstat to find the Process ID (PID) binding the disputed port (replace 5432 with your failing port number):
sudo lsof -i :5432
Alternatively, use ss or netstat:
sudo ss -tulpn | grep :5432
Step 2: Terminate the conflicting process or service
If a local background system service like PostgreSQL or Redis is occupying the port, stop it using systemctl:
sudo systemctl stop postgresql
If an unneeded standalone process holds the port, kill it using its PID:
sudo kill -9
Step 3: Stop all running Docker containers holding ports
Check if another Docker container is using the port:
docker ps --format "table {{.ID}} {{.Names}} {{.Ports}}"
Stop conflicting containers or bring down lingering Compose stacks:
docker-compose down
Step 4: Update host port mapping in docker-compose.yml
If you prefer to keep the local host service running, change the host side (left side) of the port mapping in your docker-compose.yml. Do not change the container internal port (right side):
version: '3.8'
services:
db:
image: postgres:15
ports:
# Map host port 5433 to container internal port 5432
- "5433:5432"
environment:
POSTGRES_PASSWORD: secretpassword
Run docker-compose up -d to verify the container starts successfully on the newly assigned port.
Still Not Working?
On macOS or Linux, Docker's internal routing proxy (docker-proxy) occasionally fails to release socket bindings after an abrupt crash. In these cases, no active container shows up in docker ps, but lsof shows docker-proxy owning the port.
Restart the main Docker daemon to clear hung docker-proxy socket handles:
On Linux:
sudo systemctl restart docker
On macOS: Restart Docker Desktop from the menu bar status icon.