Coding Agents & Terminal · recorded 2026-08-29 · applies to 1 tool(s) ✓ Verified

Problem: docker run/compose fails: host port already allocated / address already in use —— Trove problem library

Verified 2026-08-29port already allocated — check docker ps for container usage, ss -tlnp for host processes, then switch ports.

Quick fix

# One-liner: first check whether a docker container holds it, then host processes, finally switch ports
docker ps | grep <port> ; ss -tlnp | grep <port>

What you will run into

docker run -p <host-port>:<container-port> or docker compose up fails to create the container with failed to bind host port 0.0.0.0:8080/tcp: address already in use or Bind for :::8090 failed: port is already allocated.

The same -p command used to work, then one day it suddenly errors — the host port is occupied.

Why this happens

-p host-port:container-port creates a port-forward listener on the host (docker-proxy listens on 0.0.0.0:host-port). A host port can be held by only one process/container at a time. Two main sources of occupation:

SourceExamples
Other host processespython http.server, nginx, VSCode port forwarding
Other docker containersAnother container mapped to the same host port (two compose services colliding, stale containers not cleaned up)

-p hostPort:containerPort creates a forwarding listener on the host (docker-proxy listening on 0.0.0.0:hostPort), mapping "host port → container port".

A host port is a global host resource that can have exactly one listener at a time — whether the occupant is a host process or another container's forward rule.

Deterministic takeaway: on port is already allocated, run ss -lntp | grep <port> to see who is listening;

if it is docker-proxy, another container owns the port — look with docker ps -a, because exited containers keep their port mappings, and "not visible in docker ps" does not mean the port is free;

if it is a host process, change the port or stop the process.

Step by step

1. First check whether a docker container holds it — Required

docker ps

Look for the port in the Ports column. If present, docker rm -f <old-container> (or stop + rm) — but first confirm no other service needs it.

2. Then check host processes — Required

ss -tlnp | grep <port>

(Or lsof -i:<port> / netstat -tulpn | grep <port>.) The PID/process name tells you who holds it — stop it if it's a temporary process, or switch ports if it's a long-running service.

3. Switch the host port (easiest) — Required

docker run -p 8081:80 <image>

In compose change the left side of ports: (e.g. "8081:80"), or manage it via an env var (${LOBE_PORT}:3210 style).

4. Check for conflicts inside compose — Diagnose

Two services in the same compose file mapping the same host port fight each other; check that the left-hand values in ports: are unique.

How to confirm it works

Works after switching ports (measured output shape):

docker run -p 8081:80 → success
docker port <container> → 80/tcp -> 0.0.0.0:8081

Other environments

EnvironmentNotes
Host process holds itLocate PID with ss -tlnp, stop the process or switch ports (measured chain A)
Container holds itLocate via docker ps Ports column, rm -f the old container (measured chain B)
Inside composeLeft-hand values of ports must be unique
IPv6 sideBind for :::8090 failed = container-occupation form (measured)

Symptom

docker run -p <host-port>:<container-port> or docker compose up fails to create the container, in two typical forms:

# Form 1: another process on the host holds the port
docker: Error response from daemon: failed to set up container networking:
driver failed programming external connectivity on endpoint <name>:
failed to bind host port 0.0.0.0:8080/tcp: address already in use

# Form 2: another docker container holds the port (often reported on the IPv6 side)
docker: Error response from daemon: failed to set up container networking:
driver failed programming external connectivity on endpoint <name>:
Bind for :::8090 failed: port is already allocated

Key traits: the error always contains port is already allocated or address already in use and names the host port (0.0.0.0:PORT / :::PORT); the same -p command worked before and broke one day; or it fails right away when following a tutorial/another compose file (port collision).

Cause

-p host-port:container-port creates a port-forward listener on the host (docker-proxy listens on 0.0.0.0:host-port). A host port can only be held by one process/container at a time. Two main sources:

  1. Another process on the host: you, the system, or another service (python http.server, nginx, editor port forwarding) holds it — most common;
  2. Another docker container: another container's -p maps the same host port (including two services in one compose file, or a leftover old container).

Solution

  1. Check docker containers first: docker ps (look at the Ports column for the port). If found, docker rm -f <old-container> (or docker stop + docker rm) — make sure nothing else needs it first.
  2. Then check host processes: ss -tlnp | grep <port> (or lsof -i:<port> / netstat -tulpn | grep <port>) — the PID/process name tells you who holds it; stop temporary processes, or change the port for long-running services.
  3. Change the host port (easiest): -p 8081:80 to an unused port; in compose edit the left side of ports: (e.g. "8081:80") or manage ports via environment variables (${LOBE_PORT}:3210).
  4. Check for in-compose collisions: two services in the same compose file mapping the same host port fight each other — make the left-side values unique.
Verification Evidence
  • Local repro (2026-08-29, WSL Ubuntu, docker 29.1.3, alpine:3.20):
  • Chain A (host process): python3 http.server on 8080 → docker run -p 8080:80 → failed to bind host port 0.0.0.0:8080/tcp: address already in use (exit 125); ss -tlnp pinpointed the python3 process (PID visible); after killing it, -p 8081:80 succeeded — docker port shows 80/tcp -> 0.0.0.0:8081, docker-proxy listening on 0.0.0.0:8081 and [::]:8081;
  • Chain B (container): container 1 -p 8090:80 OK → container 2 taking the same port → Bind for :::8090 failed: port is already allocated (exit 125); docker ps Ports column identified the old container; after docker rm -f, the same port worked again.

Evidence details kept locally (2026-08-29)

Related canonicals

Read in order: precondition -> same root / same domain / related:

Applicable tools (1)

This problem is linked from the tool pages below — reachable from either side.

docker

Bundled solutions (combos)

This problem is part of the following verified bundles.

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

Source: https://github.com/lobehub/lobehub/issues/5700

← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk