排障的基本原则#
不要只看浏览器页面,也不要看到报错就立即重装 Docker。按照从底层到上层的顺序缩小范围:
1. Docker CLI 是否可用
2. Docker Engine 是否运行
3. 镜像是否构建成功
4. 容器是否存在和运行
5. 进程是否监听预期端口
6. Docker 网络和 DNS 是否正常
7. HTTP 是否返回正确状态
8. 代理路径和业务数据是否正确
9. 浏览器是否仍在使用缓存每一层都使用对应证据,不要凭感觉判断。
错误一:找不到 docker 命令#
现象#
The term 'docker' is not recognized...原因#
Docker Desktop 已安装,但 Docker CLI 所在目录没有进入当前终端的 PATH。
本次安装位置:
C:\Users\LX\AppData\Local\Programs\DockerDesktop\resources\bin临时处理#
PowerShell:
$env:Path += ';C:\Users\LX\AppData\Local\Programs\DockerDesktop\resources\bin'验证:
docker version如果只有 Client、没有 Server,应检查 Docker Desktop 和 Docker Engine 是否已启动。
错误二:invalid reference format#
现象#
docker: invalid reference format原因#
我在 CMD 中复制了 PowerShell 多行命令,反引号被当成普通字符,Docker 最终无法正确解析镜像引用。
处理#
使用单行命令:
docker run -d --name docker-demo-web -p 3000:3000 docker-demo-web:v1续行符:
CMD → ^
PowerShell → `错误三:成功后输出一串长字符串#
现象#
fca356fb0b764095e038434073c47b44c9cb07cae44feae8856539bd6b23ba9e结论#
这不是错误,是后台模式 -d 启动成功后输出的容器 ID。
查看容器:
docker ps可以使用名称、完整 ID 或唯一 ID 前缀操作容器。
错误四:docker image ls 传入两个仓库名#
现象#
docker: 'docker image ls' requires at most 1 argument原因#
docker image ls 最多接受一个位置参数:
docker image ls docker-demo-web docker-demo-docs这种写法无效。
处理#
分别查询:
docker image ls docker-demo-web
docker image ls docker-demo-docs或者使用过滤器:
docker image ls --filter "reference=docker-demo-*"错误五:构建成功,但页面仍是旧内容#
现象#
- 本机源码已经修改;
docker compose build web成功;- 浏览器仍显示旧文案。
原因#
新镜像已经生成,但运行中的容器仍引用旧镜像 ID。镜像不可变,已有容器不会原地变成新镜像。
诊断#
查看镜像:
docker image inspect docker-demo-web:v1查看容器引用的镜像:
docker inspect docker-demo-web-1处理#
docker compose up -d --force-recreate web构建和替换一起执行:
docker compose up -d --build --force-recreate web最后再使用 Ctrl+F5 强制刷新浏览器。
错误六:容器显示 unhealthy#
现象#
Up ... (unhealthy)但从 Windows 浏览器访问页面正常。
原因#
健康检查使用 localhost,容器内优先解析到 IPv6 ::1,应用只监听 IPv4。
诊断#
docker inspect docker-demo-web-1健康日志显示:
wget: can't connect to remote host: Connection refused在容器中测试明确的 IPv4 地址:
docker compose exec web wget --spider http://127.0.0.1:3000处理#
healthcheck:
test: ["CMD", "wget", "--quiet", "--spider", "http://127.0.0.1:3000"]错误七:Ping 成功,但 HTTP 返回 403#
现象#
docker compose exec web ping -c 3 docs成功且 0% 丢包。
但:
docker compose exec web wget --spider http://docs:3001返回:
HTTP/1.1 403 Forbidden原因#
Docker DNS 和网络均正常,Vite Preview Server 拒绝了 Host 为 docs 的请求。
处理#
preview: {
allowedHosts: ["docs"],
}这个案例说明 Ping 只验证较底层的网络连通性,不能证明 HTTP 应用一定接受请求。
错误八:docker compose ps 为什么只看到当前项目#
原因#
Compose 读取当前目录的 compose.yaml,获得项目名,然后通过容器标签筛选当前项目资源。
查看全部 Compose 项目:
docker compose ls查看全部运行容器:
docker ps查看当前 Compose 项目:
docker compose ps分层诊断清单#
1. Docker 层#
docker version
docker info检查 CLI 和 Engine。
2. 镜像层#
docker image ls
docker image inspect docker-demo-web:v1
docker history docker-demo-web:v1检查镜像是否存在、标签指向什么镜像以及镜像层组成。
3. 容器层#
docker ps
docker ps -a
docker compose ps
docker inspect docker-demo-web-1检查容器是否退出、使用哪个镜像、健康状态和端口配置。
4. 日志层#
docker compose logs --tail 100 web
docker compose logs --follow docs先看服务启动日志,再看请求日志和错误日志。
5. 进程和文件层#
docker compose exec web sh容器内可以执行:
pwd
ls
ps
node --version6. DNS 和网络层#
docker compose exec docs ping -c 3 web
docker network ls
docker network inspect docker-demo_backend7. HTTP 层#
docker compose exec docs wget --spider http://web:3000
docker compose exec docs wget -qO- http://web:3000/api/message8. 宿主机入口#
curl http://localhost:3001/api/message如果容器内部请求成功、宿主机失败,重点检查 ports、宿主机防火墙和端口占用。
Docker 常用命令速查#
镜像#
docker image ls
docker image ls --filter "reference=docker-demo-*"
docker image inspect IMAGE
docker image rm IMAGE
docker pull IMAGE
docker tag SOURCE TARGET容器#
docker ps
docker ps -a
docker run -d --name NAME -p HOST:CONTAINER IMAGE
docker stop NAME
docker start NAME
docker restart NAME
docker logs NAME
docker logs --follow NAME
docker exec -it NAME sh
docker inspect NAME
docker rm NAMECompose#
docker compose config
docker compose up -d
docker compose up -d --build
docker compose ps
docker compose images
docker compose logs --tail 50
docker compose logs --follow SERVICE
docker compose exec SERVICE COMMAND
docker compose stop
docker compose start
docker compose restart SERVICE
docker compose build SERVICE
docker compose up -d --force-recreate SERVICE
docker compose down
docker compose ls网络#
docker network ls
docker network inspect NETWORK磁盘占用#
docker system df安全清理原则#
暂停项目但保留容器:
docker compose stop删除当前项目的容器和网络,保留镜像:
docker compose down删除明确指定的旧镜像:
docker image rm docker-demo-web:single-stage不要在不了解影响范围时直接执行:
docker system prune -a
docker compose down -v风险:
docker system prune -a可能删除其他项目未使用的镜像和缓存;docker compose down -v会删除 Compose 管理的数据卷;- 数据卷中的数据库数据可能无法恢复。
清理前先执行:
docker system df
docker ps -a
docker image ls
docker volume ls确认目标后再删除。
最终心智模型#
源码
↓ Dockerfile + docker build
镜像
↓ docker run / compose up
容器
├─ 进程
├─ 文件系统
├─ 网络
├─ 健康状态
└─ 日志
多个容器
↓ Compose 网络和服务发现
服务系统
↓ 端口发布或反向代理
外部访问最终自测#
- 镜像、容器和 Compose 服务分别是什么?
- 为什么修改源码后需要重新构建并创建容器?
localhost在宿主机和容器中分别指向谁?ports、EXPOSE和内部容器端口有什么区别?Up与healthy有什么区别?- 服务名、容器名和容器 IP 哪个最适合应用间连接?
wget --spider与反向代理有什么区别?- 删除容器、镜像和 Volume 的风险分别是什么?
能够顺利回答这些问题,说明已经掌握了本次 Docker 实践的核心知识。
