症状
启动容器时报 Bind for 0.0.0.0:8080 failed: port is already allocated;容器启动后立即退出,但旧服务仍在占用端口;docker compose up 在旧栈未关闭时失败。
诊断
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
docker port <container-name>
lsof -i :8080
# Windows
netstat -ano | findstr :8080
docker ps 中主机端口在映射右侧;docker port 显示具体绑定(例如 0.0.0.0 还是 127.0.0.1)。如果没有容器占用,lsof 会显示本机进程;确认它是什么之后再决定是否停止。
根因
Docker 通过绑定主机套接字来发布容器端口。主机对同一地址与端口只允许一个监听者,因此第二个容器或进程无法在第一个映射存在时绑定同一主机端口。
修复
如果旧容器属于你,停止并删除它:
docker stop my-old-app
docker rm my-old-app
如果两个服务都需要运行,只修改主机侧端口:
docker run -p 8081:80 my-app
在 Compose 中为不同栈设置不同的主机端口或项目名,避免两个检出目录争抢同一绑定。
验证
docker ps显示预期的宿主机到容器映射。- 访问主机端口能到达预期容器。
- 旧容器不再运行或不占用该端口。
- 重启整个栈无需手动清理即可成功。
如果端口属于未知进程,请换一个主机端口,而不是终止不属于你的服务。移除 Compose 栈时检查是否会删除数据卷;除非确实要删除卷,否则不要使用 down -v。