The 'port is already allocated' error occurs when Docker Compose tries to bind a service to a host port that's already in use by another container or process. Find and stop the conflicting process, use a different port, or restart Docker.
The "Bind for 0.0.0.0:3000 failed: port is already allocated" error means Docker cannot start your container because the host port you're trying to use is already occupied. When you define port mappings in your `docker-compose.yml` (e.g., `ports: - "3000:3000"`), Docker needs to bind the host port (the first number) to listen for incoming connections. If another process, whether it's another Docker container, a local development server, or a system service, is already listening on that port, Docker cannot take ownership of it. This is a fundamental networking constraint: only one process can listen on a specific IP address and port combination at any time. The error message includes "0.0.0.0" because Docker by default binds to all network interfaces on the host.
Identify the process currently occupying the port:
# On Linux using lsof
sudo lsof -i :3000
# Using netstat
sudo netstat -tulpn | grep :3000
# Using ss (modern replacement for netstat)
sudo ss -tulpn | grep :3000
# On macOS
lsof -nP -iTCP:3000 | grep LISTENThe output shows the process name and PID. If you see docker-proxy, another Docker container has the port.
If another container is using the port, stop it:
# List running containers with their ports
docker ps --format "table {{.Names}}\t{{.Ports}}"
# Stop a specific container
docker stop <container_name>
# Or stop all containers from another compose project
cd /path/to/other/project
docker-compose downIf the port is held by a container from the same project:
# Stop and remove all containers from this project
docker-compose downIf a local process (not Docker) is using the port:
# Find the PID from lsof output
sudo lsof -i :3000
# Kill the process
kill <PID>
# Force kill if needed
kill -9 <PID>
# Or if it's a system service
sudo systemctl stop nginx
sudo systemctl stop apache2For development servers, use Ctrl+C in their terminal or close the IDE that started them.
If you can't stop the conflicting process, change the host port in docker-compose.yml:
services:
web:
image: myapp
ports:
- "3001:3000" # Changed host port from 3000 to 3001The format is HOST_PORT:CONTAINER_PORT. Only the host port needs to be unique; multiple containers can use the same internal port.
Update any references to the port in your browser, API clients, or environment variables.
Sometimes containers from previous sessions hold ports. Clean them up:
# Remove all stopped containers
docker container prune
# Or remove containers from a specific project
docker-compose down --remove-orphans
# Force remove all containers for this project
docker-compose rm -f
# Nuclear option: remove ALL stopped containers
docker rm $(docker ps -aq)Then try docker-compose up again.
If the port appears free but Docker still reports it as allocated, restart Docker:
# Linux
sudo systemctl restart docker
# macOS (Docker Desktop)
# Click the Docker icon in the menu bar > Restart
# Or from the command line
killall Docker && open /Applications/Docker.app
# Windows (Docker Desktop)
# Right-click Docker icon in system tray > RestartWait for Docker to fully restart before running docker-compose again.
Ensure your docker-compose.yml doesn't have duplicate port mappings:
# WRONG: Two services using the same host port
services:
web:
ports:
- "3000:3000"
api:
ports:
- "3000:8080" # Conflict! Same host port 3000
# CORRECT: Unique host ports
services:
web:
ports:
- "3000:3000"
api:
ports:
- "3001:8080" # Different host portAlso check for implicit duplicates with TCP/UDP:
# These conflict (tcp is the default):
ports:
- "8080:8080"
- "8080:8080/tcp"### Understanding Docker Port Allocation
When Docker Compose starts a service with port mappings, Docker:
1. Creates a docker-proxy process for each port mapping
2. Binds that proxy to the host's IP and port
3. Forwards traffic from the host port to the container's internal port
You can see active proxies with ps aux | grep docker-proxy.
### Binding to Specific Network Interfaces
Instead of binding to all interfaces (0.0.0.0), bind to a specific IP:
services:
web:
ports:
- "127.0.0.1:3000:3000" # Only accessible from localhost
- "192.168.1.100:3001:3000" # Specific network interfaceThis can avoid conflicts if another service is bound to a different interface on the same port.
### Dynamic Port Assignment
Let Docker choose an available port automatically:
services:
web:
ports:
- "3000" # Container port only; Docker assigns host portFind the assigned port with:
docker-compose port web 3000### Port Conflicts in CI/CD Pipelines
In CI environments where multiple jobs may run simultaneously:
services:
web:
ports:
- "${HOST_PORT:-3000}:3000" # Use environment variableRun with: HOST_PORT=3005 docker-compose up
### macOS: AirPlay Port Conflicts
macOS Monterey and later use ports 5000 and 7000 for AirPlay Receiver. Disable it at:
System Settings > General > AirDrop & Handoff > AirPlay Receiver
Or simply use different ports in your docker-compose.yml.
### Docker Desktop Quirks
On Docker Desktop (macOS/Windows), the Docker daemon runs in a VM. Sometimes port bindings get "stuck" even after containers stop. Restarting Docker Desktop usually resolves this. If it persists, try:
# Reset Docker Desktop to factory defaults (loses all data!)
# Only use as a last resort
docker system prune -a --volumesimage operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub