docker compose up -d, and one container stays down:
Bind for 0.0.0.0:5432 failed: port is already allocated
Then npm run dev adds its own version:
Error: listen EADDRINUSE: address already in use :::3000
Same problem both times: two things want one host port. And most of the time both of them are already written in the repo. Two compose services copied from one snippet, both "5432:5432". An API published on ${API_PORT:-8080} with API_PORT=3000 in .env, next to a next dev that defaults to 3000.
The usual causes
- Two services or two compose projects publish the same host port
- Another checkout's containers are still running
- A local Postgres/Redis already listens, or on a Mac, AirPlay Receiver holds 5000 and 7000
- Framework defaults collide: Next/Nuxt 3000, Vite 5173, Django/uvicorn 8000, Flask 5000
- A
.envDB_PORTis the port you connect to, so changing it does not move the binding (dify#14442)
Vite is sneakier: without server.strictPort it just moves to 5174, and your OAuth callback breaks with no port error at all.
Fix it by hand
ss -ltnp 'sport = :5432' # Linux
lsof -nP -iTCP:5432 -sTCP:LISTEN # macOS
docker ps --filter publish=5432 # another project's container?
Then stop the stale project, move one host port ("127.0.0.1:5433:5432", the container side stays the same), or drop ports: if only other containers talk to it. The 127.0.0.1 matters: a bare "5432:5432" listens on every interface.
Catch it before anything runs
I built PortClash, a free VS Code extension that reads every declared port in your workspace (compose with .env interpolation, .env*, package.json scripts, Vite/Next/Nuxt/Angular/Astro/Django/Flask/uvicorn defaults, devcontainer.json, launch.json, Kubernetes) and lines them up:
- PC001 (Error): two different sources bind the same host port
- PC002: port 5000/7000 (AirPlay) or a privileged port for a dev server
-
PC003 (Warning): a compose database published on
0.0.0.0 -
PC004: a
process.env.PORT || 3000fallback that disagrees with.env/ compose - PC005 (opt-in): a declared port is already in use on this machine
The status bar shows Ports: 9 · 1 clash, and Find Free Port Near... suggests a port nobody in the repo claims. It works in a fresh clone with nothing running. No telemetry, no network, no child processes. It is static and best-effort: runtime-computed ports and compose profiles are not evaluated.
It gets its own activity bar icon with a badge, and a Ports panel listing each port and the lines that claim it.
code --install-extension jaytankdev.portclash
Source (MIT): github.com/jay-tank/portclash
Full write-up (every source it reads, the manual fixes, limitations, FAQ): Bind for 0.0.0.0:5432 failed: port is already allocated - find port clashes before you run docker compose up
Top comments (0)