跳到主要内容

01 常见问题排查

按「现象 → 原因 → 解决」整理 Docker 使用中最高频的问题。排查任何问题前,先记住万能三板斧:

docker compose ps # 1. 看状态
docker compose logs 服务名 # 2. 看日志
docker compose config # 3. 看最终生效的配置

1. 容器启动即退出(Exited)​

现象:docker ps -a 里 STATUS 显示 Exited (1) xxx ago。

排查:先看日志找报错:

docker logs 容器名

常见原因:

日志特征原因解决
应用报错堆栈代码/配置错误按堆栈修
exec format error镜像架构不对(ARM 机器跑了 x86 镜像)拉对应架构镜像,或构建时指定 --platform linux/amd64
没有任何日志,Exited (0)容器内没有前台进程,跑完就退了CMD 必须是前台运行的命令(如 nginx -g "daemon off;")
MYSQL_ROOT_PASSWORD ... not set必填环境变量没传补上环境变量

2. 端口相关​

端口被占用​

现象:Bind for 0.0.0.0:8080 failed: port is already allocated 或 address already in use。

解决:找到占用者,换端口或停掉它:

# Linux
sudo lsof -i :8080
# 或
sudo ss -tulnp | grep 8080

# Windows (PowerShell)
netstat -ano | findstr :8080

端口通了但访问不到服务​

现象:容器 Up、端口映射也在,但浏览器访问不通。

最常见原因:容器里的服务监听了 127.0.0.1 而不是 0.0.0.0。

# 验证:进容器里能通,外面不通,基本就是这个问题
docker exec -it 容器名 sh
wget -qO- http://localhost:8000

解决:把服务的监听地址改成 0.0.0.0(uvicorn 加 --host 0.0.0.0,Node 服务 listen 时传 0.0.0.0,等等)。

3. 容器互联不通​

现象:应用容器连不上数据库容器,报 Connection refused 或 Name or service not known。

排查清单:

  1. 连接地址写的是服务名而不是 localhost 吧?容器里的 localhost 是容器自己
  2. 两个容器在同一个网络吗?docker network inspect 网络名 看看
  3. 用 docker run 手动起的容器,在默认 bridge 网络里不能用容器名互访——建自定义网络或改用 Compose
  4. 数据库真的就绪了吗?MySQL 首次初始化要几十秒,用 depends_on + condition: service_healthy
# 在应用容器里测试连通性
docker compose exec api ping mysql
docker compose exec api sh -c "wget -qO- telnet://mysql:3306 || true"

4. 数据问题​

改了 MySQL 密码环境变量但不生效​

环境变量只在数据卷为空的首次初始化时生效。已初始化过的库,改 compose 里的密码变量没用。要么进容器用 SQL 改密码,要么(测试环境)docker compose down -v 删卷重来。

容器删了数据没了​

没挂数据卷。数据类容器(MySQL/Redis/MinIO 等)必须给数据目录配卷,参考 数据卷与网络。

挂载目录后容器里是空的 / 文件不见了​

绑定挂载会用宿主机目录覆盖容器内目录。比如把空目录挂到 /usr/share/nginx/html,容器里原来的欢迎页就被「盖住」了。这是特性不是 bug:想初始化内容用命名卷(首次挂载会把镜像内容拷进卷),或者提前把文件放进宿主机目录。

Permission denied(挂载目录没权限)​

容器内进程的 UID 和宿主机目录属主不一致。解决:

# 看容器用什么 UID 跑
docker exec 容器名 id
# 把宿主机目录 chown 成这个 UID
sudo chown -R 1000:1000 /data/mydir

5. 磁盘爆满​

现象:服务器磁盘 100%,罪魁祸首常是 Docker。

# 看 Docker 占了多少
docker system df

# 一键清理:停止的容器 + 无用网络 + 悬空镜像 + 构建缓存
docker system prune

# 更狠:连所有未被使用的镜像一起删
docker system prune -a

# 容器日志也常是大头,找出大日志文件
sudo du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail

预防:所有服务配日志上限(max-size: "10m"),定期跑 docker system prune。

6. 构建问题​

拉取镜像超时​

failed to resolve source metadata / i/o timeout——网络问题,配镜像加速(见 安装Docker 第 4 节)。

构建时 pip/npm 下载慢或失败​

在 Dockerfile 里用国内源:

RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN npm ci --registry=https://registry.npmmirror.com

改了代码但构建没变化(缓存问题)​

确认部署命令带了 --build;仍然不对就强制不用缓存:

docker compose build --no-cache 服务名
docker compose up -d

7. Compose 配置报错​

报错原因
yaml: line N: mapping values are not allowedYAML 缩进错误,冒号后面少了空格
The "XXX" variable is not set.env 里没定义这个变量(或 .env 不在 compose.yaml 同目录)
service "xxx" depends on undefined servicedepends_on 写了不存在的服务名
port is already allocated端口冲突,见第 2 节

排查利器:docker compose config,它会在启动前就把语法错误、变量缺失暴露出来。

8. 实在不行的终极重置​

测试环境专用(会删数据,生产环境三思):

docker compose down -v # 停掉并删卷
docker compose up -d --build # 从零重建

小结​

  • 遇到问题先 ps → logs → config,九成问题日志里有答案
  • 高频四坑:监听 127.0.0.1、用 localhost 连别的容器、没挂数据卷、磁盘被日志塞满
  • 环境变量初始化只在数据卷为空时生效
  • 定期 docker system prune + 日志限额,磁盘才不会爆

配合 02-常用命令速查 使用效果更佳。