Docker Desktop 与 WSL 内手动安装的 Docker 冲突本质是守护进程争用同一套底层资源(如 /var/run/docker.sock 和 2375/2376 端口),导致 permission denied 或 connection refused;应只保留一种使用方式:若用 Docker Desktop 功能,就彻底卸载 WSL 中手动安装的 Docker 及其配置(包括 /etc/docker/daemon.json)并禁用相关服务;若需直连原生 dockerd,则必须退出 Docker Desktop 并确保 wsl -l -v 中无 docker-desktop 运行;Docker Desktop 默认已通过 WSL 集成将 Windows CLI 代理至其内部 daemon,无需在 WSL 中重复安装。

WSL 里装了 Docker,Docker Desktop 又启动失败?先停一个
Windows 上同时运行 Docker Desktop 和 WSL 内部手动安装的 Docker dockerd,大概率会抢 /var/run/docker.sock 或 2375/2376 端口,导致其中一个报 permission denied 或 connection refused。这不是配置错误,是两个守护进程真正在争同一套底层资源。
最直接有效的做法是:只保留一种使用方式。开发中绝大多数人不需要同时开两套 —— Docker Desktop 已经接管了 WSL2 发行版里的 docker-desktop 和 docker-desktop-data 发行版,它内部的 dockerd 就跑在那儿,你再手动装一套纯属冗余。
- 如果你用 Docker Desktop 的 GUI、Kubernetes 面板、镜像自动同步等功能,就彻底卸载 WSL 里的手动 Docker:
sudo apt purge docker-ce docker-ce-cli containerd.io,再删掉/etc/docker/daemon.json(如果存在) - 如果你坚持要在 WSL 终端里直连原生
dockerd(比如调试 daemon 行为、用非 root 用户跑),那就关掉 Docker Desktop:右下角托盘图标 → 右键 →Quit Docker Desktop,并确认wsl -l -v中没有docker-desktop在 Running 状态 - 别试图让两者共存监听不同 socket —— WSL2 的
docker.sock路径(/var/run/docker.sock)和 Docker Desktop 暴露的 socket 是绑定在同一套命名空间里的,改路径不解决问题
为什么 wsl --list -v 显示两个 docker 相关发行版?
Docker Desktop 安装后会自动注册两个 WSL 发行版:docker-desktop(运行 dockerd)和 docker-desktop-data(存放镜像、容器卷)。它们是专用发行版,不对外暴露 shell,也不该被手动修改或升级。
你手动在 Ubuntu 发行版里装的 Docker,和这两个发行版完全无关 —— 它们彼此隔离,但共享宿主机的虚拟化层和网络栈,所以端口、socket、cgroup 控制器仍会冲突。
- 检查是否误启了多个 dockerd:
ps aux | grep dockerd在每个 WSL 发行版里都执行一遍,确认只有一处输出(通常是docker-desktop里的那个) - 不要运行
sudo service docker start或sudo dockerd在你的 Ubuntu 发行版里 —— 这会强行拉起第二个守护进程 - 若已启动,杀掉:
sudo pkill -f dockerd,然后禁用开机自启:sudo systemctl disable docker(如果用了 systemd)
想在 WSL 终端里用 docker 命令,但不想装两套?
可以。Docker Desktop 默认已把 docker CLI 注入到 Windows PATH,并通过 WSL 集成自动代理命令到其内部的 docker-desktop 发行版。你不需要、也不应该在 WSL 里再装 CLI。
验证方式:在任意 WSL 终端(比如 Ubuntu)里直接运行 docker ps —— 如果能列出容器,说明通路已通;如果报 command not found,说明集成没开。
- 打开 Docker Desktop 设置 →
General→ 勾选Use the WSL 2 based engine(必须) - 再进
Resources → WSL Integration→ 启用你正在用的发行版(如Ubuntu-22.04) - 关闭终端重开,或运行
source ~/.bashrc(如果用了 bash) - 此时
which docker应返回/usr/bin/docker(符号链接),实际调用的是 Windows 下的 CLI,转发给 WSL2 内部的 daemon
删完手动 Docker 还报错?残留配置和旧发行版是真凶
很多人 purge 掉包后仍启动失败,是因为没清理干净两处东西:一是 WSL 里残留的 /etc/docker/daemon.json(哪怕空文件也会让 CLI 初始化失败),二是旧的、非 Docker Desktop 创建的 WSL 发行版(比如你曾经手动导出过 docker 相关的 distro)。
- 删配置:
sudo rm -f /etc/docker/daemon.json,然后sudo systemctl reset-failed docker(如果用了 systemd) - 查冗余发行版:
wsl -l -v,看有没有名字含docker、dockerd、docker-test等非官方的条目;有就卸载:wsl --unregister <name></name> - 重启 WSL:
wsl --shutdown,再开终端测试 - 极端情况:Docker Desktop 安装目录(
%LOCALAPPDATA%\Docker)下有残留的settings.json或旧日志,可清空整个目录后重装(注意备份settings.json里自定义的镜像源等)
dockerd 的唯一控制权 —— 默认答案就是 Docker Desktop。手动安装那套,除非你明确需要绕过 Desktop 的抽象层做底层调试,否则全是干扰项。


















