ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Docker 常见报错排查:权限拒绝、端口占用、容器退出

Docker 常见报错排查:权限拒绝、端口占用、容器退出 Docker 报错时先分清是连不上守护进程、宿主机端口冲突还是容器里的程序退出。本文面向 Linux 上的 Docker 入门用户提供对应检查命令、修复分支和成功判断帮助你保留现有服务与数据逐步恢复应用。文章目录1. 先对照错误选一条排查路线2. permission denied先确定你连接的是哪个 Docker2.1 确认是本机普通安装再检查服务2.2 按使用方式选择权限方案3. 端口占用查宿主机再改映射左侧4. 容器无法启动不要只盯着 restart5. 留下一份下次能用的排查记录1. 先对照错误选一条排查路线本文的系统命令面向使用 systemd 的 Ubuntu、Debian 等 Linux 主机。Docker Desktop、rootless Docker 或远程 Docker 环境需要先确认连接位置再使用相应管理入口。下面是常见错误片段实际文本可能因版本不同略有变化看到的现象首先检查本文对应章节permission denied涉及 Docker socket当前用户、连接地址、socket 权限第 2 节Cannot connect to the Docker daemoncontext、连接地址、守护进程状态第 2 节address already in use/port is already allocated宿主机端口、已有监听者第 3 节容器显示Exited或不断Restarting容器日志、退出状态、配置第 4 节图 1先找到对应分支。端口冲突不需要重装 Docker程序退出也不一定是守护进程故障。2. permission denied先确定你连接的是哪个 DockerDocker CLI 是客户端真正创建容器的是 daemon也就是守护进程。context 是客户端保存的连接配置切到远程 context 后操作对象也会改变。在出现错误的同一个终端运行dockercontextlsdockercontext showprintf%s\n${DOCKER_HOST:-未设置}dockerinfo先看当前 context 和DOCKER_HOST。它们可能让客户端连接到远程主机或另一个 socket不能默认所有错误都来自本机/var/run/docker.sock。Docker 守护进程排查文档2.1 确认是本机普通安装再检查服务如果使用本机 rootful Docker、默认 socket并且主机由 systemd 管理sudosystemctl statusdocker--no-pagerls-l/var/run/docker.sock服务为inactive时有管理权限的用户可以启动它sudosystemctl startdockersudodockerinfo服务已运行、普通用户报权限错误而sudo docker info能返回服务端信息才更符合访问权限问题。这里的比较只适用于同一个本机默认 daemonsudo可能使用另一套用户配置不能用于证明远程 context 的权限已经修复。2.2 按使用方式选择权限方案偶尔管理本机 rootful Docker可在明确授权的管理操作中使用sudo。长期使用时再评估 Docker 组或 rootless 模式。Docker 官方明确说明Docker 组具有 root 级别权限。不要为了消除报错直接把 socket 改为chmod 666也不要把加入 Docker 组当成所有机器的默认修复。Linux 安装后配置rootless 模式由普通用户运行 daemon管理方式与 socket 路径不同。若已经采用 rootless优先检查对应用户的服务和 context不要混用本机系统服务的判断。Rootless 官方说明**本节成功判断**在目标连接下运行docker info能返回 Server 信息。仅打印客户端版本不足以证明 daemon 可用。3. 端口占用查宿主机再改映射左侧假设项目准备使用宿主机 TCP 8080 端口在运行 Docker daemon 的那台 Linux 主机上检查sudoss-ltnpsport :8080dockerps--formattable {{.Names}}\t{{.Ports}}ss用来找系统监听者Docker 列表用来核对已有容器的端口发布。不要看到一个 PID 就结束进程先确认它属于自己的重复开发服务还是正在使用的其他应用。图 2VS Code 的 Container Explorer 可以查看容器并打开右键菜单。先找目标容器再使用日志或检查入口菜单名称随扩展版本可能变化。删除按钮不属于本篇的第一步排查操作。图源Microsoft / VS Code 容器文档© Microsoft Corporation按 CC BY 3.0 US 使用动画未修改。如果原有服务需要保留可修改新项目的宿主机端口。例如原配置是127.0.0.1:8080:80将项目web服务的ports改为ports:-127.0.0.1:8081:80这段要放在对应服务下面保留正确缩进不能另建第二个同级ports字段。然后在原项目目录应用配置dockercompose config-qdockercompose up-dwebdockercomposepscurl--fail--show-error http://127.0.0.1:8081/web替换成实际服务名。config -q检查配置up -d web根据配置创建或更新指定服务仅执行restart不会应用新的端口映射。图 3端口冲突时通常调整中间的宿主机端口。容器端口必须对应程序实际监听位置改映射不会替你修改应用配置。Docker 端口发布说明这里绑定回环地址只用于本机访问或受控转发。若 Docker daemon 在云服务器上127.0.0.1属于服务器本地电脑的浏览器不能直接访问它。**本节成功判断**映射显示新端口实际请求得到预期内容原有服务仍可正常访问。没有查到监听者时还要核对错误发生的主机、协议和时点。4. 容器无法启动不要只盯着 restart在项目目录查看已退出的服务与最后一段日志dockercomposeps-adockercompose logs--tail100web非 Compose 容器使用docker ps -a和docker logs --tail100 容器名。默认列表可能漏掉已经停止的容器因此-a很重要。容器列表说明图 4在 VS Code 中打开 Compose 文件把鼠标放在image等字段上可查看提示。截图中的旧示例展示编辑入口本文配置按当前 Compose 规范编写不需要照抄图里的version或latest。图源Microsoft / VS Code 容器文档© Microsoft CorporationCC BY 3.0 US原图未修改。根据日志中的第一条有效错误处理日志或状态线索检查方向处理后怎样确认配置解析失败YAML 缩进、字段、应用配置语法配置检查通过启动日志不再报同一错误文件不存在宿主机文件是否存在、挂载目标路径容器能读到正确文件permission denied 涉及业务目录运行用户和数据目录权限用所需最小权限恢复访问启动命令找不到镜像内容、入口命令、工作目录主进程能启动并持续执行服务连接数据库失败服务名、凭据、数据库是否就绪实际连接或业务请求成功Docker 日志主要来自程序的标准输出和标准错误。程序只把日志写进文件时docker logs可能没有关键内容需要按应用文档找对应日志文件。容器日志说明继续查看目标容器状态。把demo-web-1换成ps -a中的实际名称dockerinspect--format{{json .State}}demo-web-1重点看ExitCode、OOMKilled和Error。退出码 137 常与 SIGKILL 有关但不能单凭它断言内存不足还要对照 OOM 状态与主机记录。命令正常结束的任务容器也可能显示Exited (0)它与需要持续运行的 Web 服务不同。容器运行与退出状态图 5先查日志再看状态最后验证业务。错误原因解决后在项目目录执行docker compose up -d web再重复状态、日志和实际请求检查。5. 留下一份下次能用的排查记录记录错误原文、系统与 Docker 版本、context、相关服务、改动和验证结果。不要把数据库密码、API 密钥或完整环境变量贴进公开评论。不需要用docker system prune --volumes清理整台主机来排查单个服务。涉及数据目录或数据库时先完成可恢复备份再处理容器重建。下一步可把端口、挂载和日志选项整理进compose.yaml。确有长期运行需求时再将同一项目部署到云服务器并逐项核对远程连接、访问入口、备份和费用。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进