Skip to content

排错与最佳实践 ​

第一部分:故障排查 ​

通用排查流程 ​

① docker ps -a         看容器状态(Exited?Restarting?)
② docker logs <c>      看应用输出(报错关键字)
③ docker inspect <c>   看配置/退出码/挂载/网络
④ docker exec -it <c> sh  进入现场验证(若还活着)
⑤ docker run --rm <img> sh  用一次性容器复现

常见问题 ​

容器启动后立刻退出(Exited) ​

原因:前台进程结束了(很多镜像默认命令是短命令,或应用报错后退出)。

bash
docker ps -a                 # 确认状态
docker logs <c>              # 看报错
docker inspect -f '{{.State.ExitCode}}' <c>   # 退出码
  • 排查:docker run -it --rm <img> sh 手动跑启动命令,看真实报错。
  • 用 docker run --rm <img> sh -c "..." 复现。

端口已占用 ​

Error: ... bind: address already in use
bash
# 查看谁占用(Linux/WSL2)
sudo lsof -i :8080          # 或 ss -tlnp | grep 8080
# Windows 侧(PowerShell)
netstat -ano | findstr :8080
# 换一个宿主机端口
docker run -d -p 8081:80 nginx

Windows 上浏览器打不开容器端口(localhost 无效) ​

现象:容器正常运行、docker ps 显示端口已映射,但 Windows 浏览器开 http://localhost:8080 连接被拒绝。

原因:WSL2 与 Windows 是两套独立网络栈,容器端口发布在 WSL2 内部,Windows 的 localhost 不一定能转发到它。

bash
# ① 先确认 WSL 这一层是通的
docker ps                                  # 端口映射是否存在
curl -I http://127.0.0.1:8080              # WSL 内自检
powershell
# ② 取 WSL 的 IP,然后用它访问
wsl hostname -I                            # 例如 172.24.135.42
curl.exe http://172.24.135.42:8080
text
# ③ 浏览器访问 http://<WSL-IP>:8080

常见原因与处理:

原因处理
映射写成了 -p 127.0.0.1:8080:80改成 -p 8080:80,绑定到所有网卡
WSL 重启后 IP 变了重新执行 wsl hostname -I,用新 IP
想让 localhost 直接可用(Win11 22H2+).wslconfig 设 networkingMode=mirrored 后 wsl --shutdown
局域网/手机等外部设备要访问Windows 上做 netsh interface portproxy + 防火墙放行

详见 安装与环境 → 从 Windows 访问容器端口。

容器之间无法互通 ​

  • 确认在同一个自定义网络(默认 bridge 不支持按名解析)。
  • 用 docker network inspect <net> 确认双方都在。
  • 用 docker run --rm --network <net> busybox nslookup <服务名> 验证 DNS。

无法连接到 Docker 守护进程 ​

Cannot connect to the Docker daemon at unix:///var/run/docker.sock
平台处理
macOScolima start,再 docker context use colima
WSL2sudo service docker start(或启用 systemd 后 sudo systemctl start docker)
Linuxsudo systemctl start docker

另外确认当前用户在 docker 组(groups 查看),或 sudo 执行。

权限拒绝(Permission denied) ​

bash
# 容器内读写挂载目录报错
# 排查:宿主目录权限、容器运行用户(--user / USER)
# 挂载卷初始化权限:以 root 启动一次或调整用户 uid
docker run -d -v data:/data --user 1000:1000 app

磁盘空间不足 ​

bash
docker system df            # 定位占用(Images/Containers/Volumes/Build Cache)
docker system prune -a      # 清理(先确认无重要数据)
docker volume prune

镜像拉取慢 / 超时 ​

  • 配置镜像加速(见 安装与环境)。
  • 或设置代理:守护进程配置 "proxies",构建时用 --build-arg/--network=host。

容器内存溢出被 kill ​

bash
docker inspect -f '{{.State.OOMKilled}}' <c>   # true 说明被 OOM
docker run -d -m 512m --memory-swap 512m app    # 适当放开限制

调试利器 ​

bash
# 覆盖入口,直接进 shell 排查镜像内部
docker run -it --rm --entrypoint sh <img>

# 交互式跑某个层(定位问题层)
docker run -it --rm <img> sh

# 实时看资源
docker stats

# 查看完整配置(JSON)
docker inspect <c> | less

第二部分:安全与最佳实践 ​

镜像最佳实践 ​

  1. 固定基础镜像版本(nginx:1.25-alpine 而非 nginx:latest)。
  2. 优先官方镜像与轻量变体(alpine/slim)。
  3. 多阶段构建,缩小体积。
  4. 非 root 用户运行:USER。
  5. 合并 RUN、删除包缓存。
  6. 只 COPY 必要文件,写 .dockerignore。
  7. 用 HEALTHCHECK 暴露健康状态。
  8. 及时扫描漏洞:docker scout quickview <img>(或 Trivy 等工具)。

运行最佳实践 ​

  1. 生产用 --restart unless-stopped。
  2. 设置资源上限(--memory / --cpus)。
  3. 数据用命名卷持久化,别依赖容器可写层。
  4. 敏感配置用环境变量/secret,别写进镜像。
  5. 最小权限:限制端口只绑定内网(127.0.0.1:3306:3306)。
  6. 定期 docker system df 清理。

生产经验清单 ​

  • 用 Compose 管理多服务,YAML 纳入版本库。
  • 有状态服务(数据库)单独卷、健康检查、备份计划。
  • 日志统一收集:docker logs 驱动配置(json-file 默认,可配 loki/fluentd)。
  • 监控:docker stats 或 cAdvisor + Prometheus + Grafana。
  • 升级:固定版本、灰度、保留回滚镜像。

常用“救急”命令 ​

bash
docker system prune -a -f          # 清空未使用资源
docker rm -f $(docker ps -aq)      # 强制删所有容器
docker rmi $(docker images -q)     # 删所有镜像(危险)

危险命令执行前务必三思,尤其带 -f、prune、rmi $(...) 的批量操作。