Problem entry · machine-readable · 编码代理与终端

docker run / compose up 报 port is already allocated / address already in use(端口被占用)

本页嵌入 #trove-entity JSON(本条目全量结构化数据);全库数据见 /agent/trove.json。

元数据

iddocker-port-already-allocated收录2026-08-29
问题域编码代理与终端主题分组容器与 WSL
适用工具docker · 外部工具

症状

`docker run -p <宿主端口>:<容器端口>` 或 `docker compose up` 时容器创建失败,两种典型报错:

```

# 形态 1:宿主上其它进程占了端口

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

# 形态 2:另一个 docker 容器占了端口(常报 IPv6 侧)

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

```

特征:报错里一定带 `port is already allocated` 或 `address already in use`,且明确指向宿主端口(0.0.0.0:PORT / :::PORT);同一个 `-p` 命令**之前能跑通**,某天突然报错;或照教程/别人的 compose 起服务时报错(端口撞车)。

原因

`-p 宿主端口:容器端口` 会在宿主机上创建一个端口转发监听(docker-proxy 监听 `0.0.0.0:宿主端口`)。宿主端口同一时间只能被一个进程/容器占用,被占就报上面的错。两大类占用来源:

1. **宿主机其它进程**:你/系统/别的服务(如 python http.server、nginx、VSCode 端口转发)占着该端口——最常见;

2. **其它 docker 容器**:另一个容器的 `-p` 映射了同一宿主端口(含 compose 里两个服务映射同一端口、或旧容器没删干净)。

解法

1. **先看是不是 docker 容器占的**:`docker ps`(看 Ports 列有没有该端口)。有就 `docker rm -f <旧容器>`(或 `docker stop` + `docker rm`),确认没有别的服务需要它再删。

2. **再看宿主机进程**:`ss -tlnp | grep <端口>`(或 `lsof -i:<端口>` / `netstat -tulpn | grep <端口>`),看到 PID/进程名就能定位是谁占的——是临时进程就停掉,是长期服务就换端口。

3. **换宿主端口(最省事)**:`-p 8081:80` 换成没被占的端口;compose 里改 `ports:` 左侧的宿主端口(如 `"8081:80"`),或把端口写成环境变量统一管理(`${LOBE_PORT}:3210` 这类)。

4. **排查 compose 内部冲突**:同一个 compose 文件里两个服务映射同一宿主端口会互相打架,逐个服务检查 `ports:` 左侧值是否唯一。

验证证据

- 本地实测(2026-08-29,WSL Ubuntu,docker 29.1.3,alpine:3.20):

- 链 A(宿主进程占用):python3 http.server 占 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` 定位到 python3 进程(pid 可见);停掉后换 `-p 8081:80` → 成功,`docker port` 显示 `80/tcp -> 0.0.0.0:8081`,docker-proxy 监听 0.0.0.0:8081 与 [::]:8081;

- 链 B(容器占用):容器 1 `-p 8090:80` 成功 → 容器 2 抢同一端口 → `Bind for :::8090 failed: port is already allocated`(exit 125);`docker ps` Ports 列定位到旧容器;`docker rm -f` 旧容器后同一端口再起成功。

- 实测复现日志(2026-08-29)

来源与证据

素材来源:https://github.com/lobehub/lobehub/issues/5700

验证证据:Evidence details kept locally (2026-08-29)