Docker

How to Fix "port is already allocated" in Docker Compose

3 min read by DebuggedIt

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 5432 or Nginx/Apache on port 80) 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-proxy process 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.