快速修复
# 一键:清掉残留的 DOCKER_HOST 再试
unset DOCKER_HOST && docker ps
你会遇到什么
docker ps 一执行就报 Cannot connect to the Docker daemon at unix:///var/run/docker.sock(老版文案)或 failed to connect to the docker API at unix:///tmp/no-such.sock(新版文案)。CLI 明明在,报的是连接问题。
WSL 里装过 Docker Desktop 又用原生 docker 的机器最容易出现——多半是 DOCKER_HOST 残留把 CLI 指到了不存在的 socket。
本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。
为什么会这样
docker CLI 通过 unix socket 与 daemon 通信(默认 /var/run/docker.sock)。连不上的三大根因:
| 根因 | 特征 |
|---|---|
| daemon 没在跑 | socket 文件不存在;原生 docker 需 systemctl start docker,Desktop 需启动应用 |
| socket 路径不对 | DOCKER_HOST 或 context 指向不存在的路径——WSL 最常见:残留 Docker Desktop 的 DOCKER_HOST=unix:///mnt/wsl/docker-desktop/shared-sockets/.../docker.proxy.sock |
| 权限不足 | socket 存在但 permission denied,用户不在 docker 组 |
报错里的路径是关键线索:指向 /var/run/docker.sock(默认)还是别处(被 DOCKER_HOST/context 改过)。
实测环境:WSL Ubuntu,docker CLI 29.1.3 / daemon 29.1.3,2026-08-29。
docker CLI 与 daemon 是「客户端-服务器」架构:CLI 本身不做任何容器操作,一切请求都通过 unix socket 走 HTTP 风格 API,所以报错永远是「连不上」,而不是「命令不存在」。
CLI 找 daemon 的寻址顺序是 DOCKER_HOST 环境变量 → 当前 context 的 endpoint → 默认 /var/run/docker.sock;残留的 DOCKER_HOST(比如 Docker Desktop 的 WSL socket 路径)会把 CLI 指到一个不存在的文件。
确定性推论:报错里写明的 socket 路径就是「CLI 实际去找的地方」,先看路径再动手——指向默认路径 = daemon 没起或权限问题;指向别处 = 寻址被环境变量/context 改过,unset DOCKER_HOST 或 docker context use default 恢复。
一步步来
1. 看报错路径 + 查环境变量 — 排查
env | grep -i docker_host
有输出 → unset DOCKER_HOST(或 export -n DOCKER_HOST)再试。实测:本机残留 DOCKER_HOST 指向 Desktop socket(文件不存在),unset 后 docker ps 恢复——daemon 其实一直在跑。
2. 看 context — 必做
docker context ls
看当前 * 的 endpoint;误配就 docker context use default。
3. socket 不存在 = daemon 没起 — 必做
ls -l /var/run/docker.sock
不存在 → sudo systemctl start docker(或 sudo service docker start)。存在但 permission denied → 用户不在 docker 组:sudo usermod -aG docker $USER 后重新登录,或临时 sudo docker ...。
4. WSL + Docker Desktop 混用 — 必做
二选一:用 Desktop 就保持 DOCKER_HOST 指向它的 socket(或 docker context use desktop-linux);用原生 daemon 就清掉 Desktop 相关环境变量/context,别让两个入口打架。
怎么确认修好了
docker ps
正常返回容器列表即恢复(实测:unset DOCKER_HOST 后恢复;复现时 DOCKER_HOST=unix:///tmp/no-such-docker.sock docker ps 精确复现报错,exit 1)。
其它环境的表现
| 环境 | 说明 |
|---|---|
| 原生 docker(systemd) | sudo systemctl start docker / service docker start |
| Docker Desktop | 启动应用 + WSL 集成;用 desktop-linux context |
| WSL 混用残留 | unset DOCKER_HOST + docker context use default |
| 非 root 用户 | sudo usermod -aG docker $USER,重登生效 |
症状
docker ps / docker run 等命令一执行就报连不上 daemon,两种文案(版本不同):
# 老版 CLI 文案
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
# 新版 CLI 文案(docker 25+)
failed to connect to the docker API at unix:///tmp/no-such.sock; check if the path is correct
and if the daemon is running: dial unix /tmp/no-such.sock: connect: no such file or directory
特征:CLI 能跑、报错的是连接(不是 command not found);报错里的路径是关键线索——指向 /var/run/docker.sock(默认)还是别处(说明被 DOCKER_HOST/context 改过);WSL 里装过 Docker Desktop 又用原生 docker 的机器最容易出现。
原因
docker CLI 通过 unix socket 与 daemon 通信(默认 /var/run/docker.sock)。连不上的三大根因:
- daemon 没在跑:原生 docker 需
systemctl start docker(或sudo service docker start);Docker Desktop 需启动应用/WSL 集成; - socket 路径不对:
DOCKER_HOST环境变量或docker context指向了不存在的 socket——WSL 里最常见:环境里残留DOCKER_HOST=unix:///mnt/wsl/docker-desktop/shared-sockets/.../docker.proxy.sock(Docker Desktop 路径),但实际用原生 daemon;或 Desktop 升级后 socket 路径变化; - 权限不足:socket 属主 root:docker(
srw-rw----),非 root 用户不在 docker 组时permission denied(报错是 connect: permission denied)。
解法
- 看报错里的路径:如果路径不是
/var/run/docker.sock,先查环境变量:env | grep -i docker_host——有就unset DOCKER_HOST(或export -n DOCKER_HOST)再试。 - 看 context:
docker context ls,看当前*的 endpoint 是什么;误配就docker context use default。 - 确认 socket 与 daemon:
ls -l /var/run/docker.sock不存在 = daemon 没起(sudo systemctl start docker/sudo service docker start);存在但报 permission denied = 用户不在 docker 组(sudo usermod -aG docker $USER后重新登录,或临时sudo docker ...)。 - WSL + Docker Desktop 混用:二选一——用 Desktop 就保持
DOCKER_HOST指向它的 socket(或用docker context use desktop-linux);用原生 daemon 就清掉 Desktop 相关环境变量/context,别让两个入口打架。 - 验证:
docker ps正常返回即恢复。
验证证据
- 本地实测(2026-08-29,WSL Ubuntu,docker CLI 29.1.3 / daemon 29.1.3):
- 基线:
/var/run/docker.sock存在(srw-rw---- root docker),docker ps 正常; - 复现 1:
DOCKER_HOST=unix:///tmp/no-such-docker.sock docker ps→failed to connect to the docker API at unix:///tmp/no-such-docker.sock ... dial unix ... no such file or directory(exit 1); - 复现 1b:
DOCKER_HOST指向 Docker Desktop 的 socket 路径(本机真实残留值/mnt/wsl/docker-desktop/shared-sockets/guest-services/docker.proxy.sock)→ 该文件不存在 → 同样报错——即本机此前「docker 全挂」的真实原因; - 排查:
docker context ls显示 default(unix:///var/run/docker.sock)与 desktop-linux 两个 context;env | grep -i DOCKER_HOST定位污染源; - 修复:unset DOCKER_HOST 后 docker ps 恢复(daemon 其实一直在跑)。
- 实测复现日志(2026-08-29)
相关 canonical
按「前置 → 同根 / 同域 / 相关」读:
- 前置(先排除):
- docker pull 失败/镜像加速(前置:daemon 没起,pull 一样报连接错)
- 端口占用 port is already allocated(前置:能报端口占用 = daemon 已正常)
- docker exec 报 not a TTY(前置:exec 也走 daemon API)
- Docker build 缓存不生效(前置:build 也依赖 daemon)
- 挂载目录 Permission denied(前置:容器能启动 = daemon 正常,权限错在挂载层)
- 同根(同一根因):
- Docker Desktop 启动失败/孤儿 socket(同根:Desktop 引擎/socket 层异常,「连不上 daemon」的 Desktop 场景根因)
适用工具 (1)
本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。
docker · 外部工具成套方案 (组合包)
这个问题包含在下列成套安装方案中。
- 容器与 WSL 环境成套配置与排查 partial
来源与证据
这条方案对你有用吗?
反馈由维护 Agent 汇总,用于重测排期与方案改进;匿名,不收集任何个人信息。
← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡