
Troubleshooting Docker 'Bind for 0.0.0.0:80 failed: port is already allocated' Error
You type docker-compose up. The logs start scrolling, and then...
Error response from daemon: driver failed programming external connectivity on endpoint... Bind for 0.0.0.0:80 failed: port is already allocated.
Your container dies. Ideally, you want your web server on port 80, but something else got there first. This is a rite of passage for every backend developer.
Here is how to hunt down the port/process ghost on Windows, Mac, and Linux.
Root Cause Analysis
A TCP/UDP port (like 80, 3000, or 8080) can only be owned by one process at a time. Docker is trying to bind the host's port 80 to your container. It fails because:
- Ghost Container: An old version of your container is still running in the background.
- System Service: On Windows, IIS or "World Wide Web Publishing Service" often grabs port 80 on boot.
- Other Apps: Skype (yes, really), Apache, or Nginx installed locally.
The Solution: Step-by-Step
1. Check for Zombie Containers
First, ensure you didn't leave a detached container running.
docker ps
If you see a container using the port, kill it:
docker rm -f <container_id>
2. Identify the Process (Windows)
If Docker isn't the culprit, the OS is. Open PowerShell / CMD as Administrator and run:
netstat -ano | findstr :80
You will see output like:
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4120
That last number 4120 is the PID (Process ID).
To find out what "4120" actually is:
tasklist /fi "pid eq 4120"
It might return httpd.exe (Apache), nginx.exe, or System.
3. Kill the Process
If it's a user app (like python.exe or node.exe), kill it:
taskkill /PID 4120 /F
If the Process Name is System (PID 4), DO NOT kill it. "System" on Port 80 usually means the World Wide Web Publishing Service (IIS).
To stop it:
- Press
Win + R, typeservices.msc. - Find World Wide Web Publishing Service.
- Right-click -> Stop (and define Startup Type to Manual if you don't need it).
4. Identify the Process (Mac/Linux)
On Unix-based systems, use lsof (List Open Files):
sudo lsof -i :80
This lists the command name and PID clearly. Kill it with:
kill -9 <PID>
Alternative Fix: Change the Port Mapping
Sometimes you can't stop the conflicting service (e.g., it's a corporate VPN or security tool). In that case, simply map Docker to a different host port.
In your docker-compose.yml:
ports:
- "8080:80" # Map Host 8080 -> Container 80
or via CLI:
docker run -p 8080:80 ...
Now access your app at localhost:8080.
Expert Tip: The "WinNAT" Bug
[!TIP] Windows User Special Sometimes
netstatshows absolutely nothing on port 80, but Docker still complains. This is often the Windows NAT Driver (WinNAT) getting stuck reserving ranges of ports. The Fix:
- Open Admin PowerShell.
net stop winnatdocker-compose up -d(Start your containers).net start winnatThis flushes the networking table and lets Docker grab what it needs.
Conclusion
Port conflicts are simple but frustrating blocks. By mastering netstat and lsof, you become the traffic cop of your machine. Always check for old containers first, then hunt for system services.