前两天有个同事问我说,想在 Windows 上跑 Docker,但不想装双系统,也不想开虚拟机,能不能直接装个软件就完事。我说能,而且只要 WSL 里已经装好 Ubuntu,从下载安装包到真正跑起来一个容器,三分钟是够的。这篇就把完整的链路走一遍:Windows 上装 Docker Desktop,再让 Ubuntu(WSL)直接使用同一个引擎。适合第一次在 Windows 上接触 Docker 的人,也适合已经装了 WSL2 但一直没搞明白怎么和 Docker 联动的人。
先给你一个心里预期:真正花时间的不是 Docker 安装,而是前面 WSL2 的准备。系统版本、虚拟化开关、WSL 内核这几个东西不到位,后面会反复报错。所以我会把“准备”和“安装”分开讲,你按顺序做,基本一次过。
1. 安装前先理清:Docker Desktop、WSL2、Ubuntu 三者到底在忙什么
很多人卡住,不是操作不会,而是没搞明白这三个东西各自负责什么。先说结论:Docker Desktop 是引擎管理入口,WSL2 是它在 Windows 上运行 Linux 容器的底层环境,而 Ubuntu(WSL)是你日常操作的终端。三者互相配合,缺一个都不顺。
1.1 为什么现在 Windows 宿主机上可以跑 Linux 容器
早期的 Windows 装 Docker 是很痛苦的。常见做法是先装一个 VirtualBox 或 Hyper-V,创建一个完整的 Linux 虚拟机,再在这个虚拟机里装 Docker。路径是够长的:虚拟机占掉几个 GB 内存,启动还要等系统引导,目录共享也经常卡。后来微软把 WSL2 做出来了,情况彻底改变。
WSL2 不是模拟器,它是一个运行在轻量级虚拟机里的真实 Linux 内核。你可以把它理解成微软帮你把 Linux 内核“缝”进了 Windows,启动一个发行版只需要几百毫秒,内存还能动态回收。因为 Docker 容器本质上是 Linux 内核上的进程隔离技术,只要这个内核在,容器就能直接跑。这就是 Docker Desktop 选择 WSL2 作为后端的原因。
如果你还在用老一代的 Docker Toolbox,或者还在 VMware 里跑一个完整 Linux 来做开发,我建议你迁移到这套方案。不是说你现有的方案跑不了,而是日常体验差距太大了:启动速度、资源占用、文件互通,都不是一个级别。
1.2 Docker Desktop 与 WSL 发行版的实际分工
Docker Desktop 安装之后,你自己看 WSL 发行版列表会发现多了两个名字:docker-desktop和docker-desktop-data。前者放 Docker 引擎运行所需的环境,后者放镜像和容器数据。这两个发行版是 Docker Desktop 自己管理的,正常情况下你不用进去操作。
你的 Ubuntu(WSL)发行版不需要也不应该安装 Docker 守护进程。它只负责提供一个用户侧环境,让你敲docker命令。Docker Desktop 会把 CLI、上下文配置自动注入到启用集成的发行版里,命令输进去,请求就会转发给引擎。
我用一个类比:Docker Desktop 是发电厂,Ubuntu 是墙上的插座。你接上插座就有电,不需要在自己家里再装一台发电机。如果你在 Ubuntu 里手动apt install docker.io,就相当于插座旁边又装了台柴油发电机,既占地方又容易和电网打架。这个坑我见过太多次了。
1.3 “三分钟安装”的底气来源:哪些步骤可以并行
标题说三分钟,前提是 WSL2 已经准备好了。在这个前提下,流程大概是:下载 Docker Desktop 安装包两分钟,安装一分钟,设置 WSL 集成半分钟,跑通 hello-world 半分钟。这是真实可达的。
但从零开始的话,三分钟不现实。卡点主要在 Windows 功能开启和重启、WSL 内核更新、Ubuntu 初始化这几步。系统如果比较老,还要手动下载内核更新包。所以我的建议是:先把 WSL2 和 Ubuntu 装好,确认wsl -l -v里版本号是 2,再开始 Docker 部分。顺序反过来虽然也能跑,但容易踩到 Hyper-V 后端和 WSL2 后端切换的混乱状态。
2. 前置三步:开启虚拟化、装好 WSL2、把 Ubuntu 放到你想要的位置
2.1 检查系统版本与 CPU 虚拟化,这一步漏了后面全白搭
装之前先花两分钟做三个检查,比装到一半报错再排查划算得多。
第一个检查系统版本。点击开始菜单输入winver回车,看 Windows 版本。Docker Desktop 在 Windows 10 64 位专业版、企业版、教育版以及 Windows 11 上都支持;家庭版也能跑,前提是系统版本不能太老,最好在 Windows 10 2004 以上。如果你还在 1903 或者 1909,也不是不能装,但 WSL2 的内核更新包和功能开关要手动处理,麻烦一些。
第二个检查 CPU 虚拟化是否开启。打开任务管理器,切到“性能”标签,点 CPU,看右下角“虚拟化”是不是“已启用”。如果是“已启用”,跳过 BIOS 操作。如果是“已禁用”,需要重启进 BIOS,找到 Intel VT-x 或 AMD SVM 之类的选项打开。不同主板位置不一样,但一般都在 Advanced / CPU Configuration 里。这一步不做,后面 WSL2 和 Docker Desktop 都会启动失败。
第三个检查 Windows 功能。控制面板→程序→启用或关闭 Windows 功能,确认“适用于 Linux 的 Windows 子系统”和“虚拟机平台”这两个勾选项是开的。如果你用的是新系统,直接用后面提到的wsl --install命令会自动开,就不用手动到这里打勾了。
| 检查项 | 操作方法 | 通过标准 |
|---|---|---|
| 系统版本 | 开始菜单输入 winver | Windows 10 2004+ 或 Win11 |
| CPU 虚拟化 | 任务管理器→CPU→虚拟化 | 已启用 |
| 虚拟机平台 | Windows 功能面板 | 两个勾选都已开启 |
2.2 新装机直接用 wsl --install,存量系统按需手动升级
如果你系统比较新,安装 WSL2 其实就一条命令。用管理员身份打开 PowerShell,执行:
wsl --install -d Ubuntu这条命令会自动完成三步:开启所需 Windows 功能、安装 WSL2 内核、下载并安装 Ubuntu 发行版。完成后会提示你重启,重启完继续初始化 Ubuntu 的用户名和密码。
如果你的系统不支持wsl --install,命令会提示找不到或者功能未启用。这时候就需要走老路线:先在上面的 Windows 功能面板里把两个勾选打开,重启,然后下载微软官方的 WSL2 Linux 内核更新包,装完再执行:
wsl --set-default-version 2接着从 Microsoft Store 搜索 Ubuntu 安装即可。
装完验证一下,在 PowerShell 里运行:
wsl -l -v如果 VERSION 列显示的是 2,说明 WSL2 正常。如果显示 1,执行:
wsl --set-version Ubuntu 2转换过程如果卡住,先把 Ubuntu 退出来,执行wsl --shutdown再试。老版本系统转换失败往往是内核更新包没装,不是发行版的问题。
2.3 从 C 盘迁移到 D 盘:export/import 的正确顺序
WSL 的 Ubuntu 默认装在 C 盘,位置在%LocalAppData%\Packages下面的 vhdx 文件里。开发环境用久了,这个文件能膨胀到好几个 GB,C 盘压力很大。想迁移到 D 盘,推荐用wsl --export加wsl --import,但顺序不能错。
先退出所有 WSL 发行版,然后在 PowerShell 里执行:
wsl --shutdown wsl --export Ubuntu D:\wsl\ubuntu.tar wsl --unregister Ubuntu wsl --import Ubuntu D:\wsl\ubuntu D:\wsl\ubuntu.tar --version 2顺序是:先 shutdown,再 export,再 unregister,最后 import。有人手滑先 unregister 再 export,相当于先删了数据再找备份,那基本就找不回来了。
导入之后有个隐藏坑:默认用户会变成 root。你之前 Ubuntu 里配置的用户名和密码还在,但默认登录变成了 root,导致文件权限、sudo 行为都和以前不一样。解决办法是进入 Ubuntu,编辑/etc/wsl.conf:
[user] default=你的用户名保存后,在 PowerShell 里执行wsl --shutdown再重新进入,就会恢复成普通用户。
另外一个建议:迁移之后,D:\wsl\ubuntu.tar这个压缩包可以留着,也可以删掉。如果担心将来系统出问题,留一份做备份成本也不高。
3. Docker Desktop 安装与首次启动的关键选项
3.1 下载渠道和安装参数:别选错版本
下载 Docker Desktop 请认准官网渠道,搜索 Docker Desktop for Windows 即可。安装包体积几百 MB,下载速度取决于网络,这一步如果慢,耐心等就行,不影响后面步骤。
安装时有几个细节值得注意。如果电脑上之前装过 Docker Toolbox,建议先卸载干净,否则旧版本创建的虚拟机可能占用端口和资源。安装过程中默认选项可以直接用,不需要改。如果你想装到 D 盘而不是 C 盘,可以用管理员 PowerShell 执行安装程序并指定目录:
Docker Desktop Installer.exe install --installation-dir=D:\Docker安装完成后桌面会出现 Docker Desktop 图标。先别急着点,确认 WSL 已经就绪,否则首次启动可能找不到后端。
这里有一个 Windows 上常见的坑:杀毒软件实时防护有时会拦截 Docker Desktop 的目录写入,导致安装到一半失败或者启动后组件损坏。如果你安装失败,可以先在杀毒软件里把安装目录和 Docker 数据目录加入排除项,再重新安装。
3.2 首次启动如何选择 Use WSL 2 instead of Hyper-V
双击 Docker Desktop 启动,首次会弹许可协议,接受之后会问你要不要使用 WSL 2。如果系统已经装好 WSL2,直接勾选 “Use WSL 2 instead of Hyper-V”。
如果启动时没有弹这个选项,可以在安装完成后的 Settings 里看到 General 标签,里面有一项 “Use the WSL 2 based engine”,勾上即可。这个选项是 Docker Desktop 的核心开关:它决定引擎跑在哪个后端上。
选 WSL2 之后,Docker Desktop 会自动创建前面说的docker-desktop和docker-desktop-data两个 WSL 发行版。你可以在 PowerShell 里执行wsl -l -v看,会发现多出两个条目。看到这两个条目,说明引擎确实跑在 WSL2 上了。
这里有个经验:如果你之前不小心选了 Hyper-V 后端,后来想切回 WSL2,改完设置后不仅要点 Apply & Restart,最好再执行一次wsl --shutdown,把旧的 WSL 状态清干净,否则偶尔会出现引擎启动失败。
3.3 启动日志怎么读:判断后端是否真的切换成功
Docker Desktop 启动后,看右下角托盘区的鲸鱼图标。图标变成静态绿色表示引擎正常,还在转圈说明启动中。启动通常需要十几秒,别因为慢就反复点重启。
打开 Dashboard,主界面会显示 “Engine running”。要确认后端是不是 WSL2,在 PowerShell 或者 Ubuntu 终端里执行:
docker info看输出里的这几项:
- Operating System: Docker Desktop
- Kernel Version: ...microsoft-standard-WSL2
如果 Kernal 里看到 WSL2 字样,说明后端切换成功。如果只有 “Cannot connect to the Docker daemon”,说明引擎没起来,下一步去看日志。
日志位置在%LocalAppData%\Docker\log\host,里面会写明具体原因。绝大多数情况是虚拟化没开,或者 Windows 功能没勾全,回到第 2 节检查一遍。
4. 建立连接:让 Ubuntu(WSL)直接使唤宿主机上的 Docker 引擎
Docker Desktop 装好只是第一步,标题里说的“与 Ubuntu(WSL)建立连接”,要靠一个叫 WSL Integration 的设置来完成。这一步不做好,你在 Ubuntu 里根本看不到 docker 命令。
4.1 Docker Desktop 设置里开启 WSL Integration
打开 Docker Desktop,进入 Settings → Resources → WSL Integration。你会看到一个开关 “Enable integration with my default WSL distro”,把它打开,然后在下面的发行版列表里勾选 Ubuntu。
勾选之后点 Apply & Restart。Docker Desktop 重启需要一点时间,等引擎恢复。
这个设置的本质,是让 Docker Desktop 把你的 Ubuntu 发行版加入“被注入”名单。注入的内容包括 docker CLI 的可执行路径、默认 context 配置,以及必要的环境变量。只有被勾选的发行版才能自动拿到这些,没勾选的其他发行版则保持纯净。
如果你用wsl --import恢复过 Ubuntu,或者发行版名字不是默认的 Ubuntu,一定要确认列表里能看到它并且已勾选。有时候新导入的发行版不会自动出现在列表,需要把 Docker Desktop 完全退出再重新打开,它才会重新扫描。
4.2 零配置背后的 docker context 机制
很多人第一次在 Ubuntu 里执行docker version时都会愣一下:怎么直接就有命令?又怎么直接就连上了引擎?原因是 Docker Desktop 做了一件透明的事:它在你的 WSL 发行版里写入了 Docker 客户端,并把默认上下文指向了自己的引擎。
你可以执行:
docker context ls会看到默认 context 是desktop-linux这一类名字,后面跟着的意思是“这是 Windows 桌面版 Docker 的上下文”。
理解了这个机制,你就知道为什么我不建议在 Ubuntu 里额外安装 docker.io 或 docker-ce。一旦你手动装了自己的 Docker 包,系统里会出现两套 CLI,版本还不一定一样,docker context可能被覆盖,结果就是命令时灵时不灵,报各种奇怪错误。
如果你确实需要连接远程服务器上的 Docker,也完全可以:在这套基础上新建一个 context,指向远程地址就行。日常开发还是保持“Ubuntu 本地 CLI + Desktop 引擎”最省心。
4.3 连接验证:hello-world、nginx,以及最常见的 docker run 参数
连接是否成功,用最经典的 hello-world 验证:
docker run hello-world如果本地没有这个镜像,Docker 会先从仓库拉取,然后运行。看到一段 “Hello from Docker!” 的英文说明,说明从 Ubuntu 终端调用引擎的完整链路已经通了。
接着跑一个 Web 服务做更明显的验证:
docker run -d --name nginx-test -p 8080:80 nginx:alpine然后打开浏览器访问http://localhost:8080,能看到 Nginx 欢迎页。这里从 Windows 浏览器访问容器端口,直接证明容器网络和端口映射都正常。
再举一个实际业务中更常用的 MySQL 例子。如果你想在 Windows 的开发环境里跑一个 MySQL 8,不需要本地安装服务,一条命令搞定:
docker run -d --name mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=你的密码 mysql:8.0这几个参数解释一下:
-d后台运行--name mysql8给容器命名-p 3306:3306把宿主机 3306 端口映射到容器 3306-e设置环境变量,这里是初始化 MySQL 的 root 密码
连接上之后,你用任何 MySQL 客户端连localhost:3306就能访问容器里的数据库。这个组合我几乎每个项目都会用到,比在 Windows 上手工安装 MySQL 服务干净得多,卸载也简单。
5. 实测中躲不开的四个坑:更新、路径、端口和权限
5.1 Windows 10 提示 WSL kernel needs update 的处理
Windows 10 专业版用户经常在安装 WSL2 或启动 Docker Desktop 时看到 “WSL 2 needs an update” 或者 “WSL kernel update required” 的提示。原因不复杂:WSL2 内核组件太旧,或者系统功能开启了但内核文件没有安装。
解决办法很简单,管理员身份打开 PowerShell,执行:
wsl --update这个命令会自动下载并安装最新 WSL2 内核。装完执行wsl --shutdown,再重新打开 Ubuntu 和 Docker Desktop。
如果你的 Windows 版本太老,wsl --update可能不存在,那就需要去微软官网下载 WSL2 Linux 内核更新包,手动安装。这个包是一个 msi 文件,装完同样要重启 WSL。有些机器需要先确认“虚拟机平台”功能真的勾上了,很多提示都是这里漏了。
遇到这种问题不要慌,它不影响你已有的 WSL 发行版数据,只是内核更新,重来一次很快。
5.2 容器数据卷与 /mnt/c 路径乱码问题
在 WSL2 里,Windows 的 C 盘会被挂载到/mnt/c,这是 WSL 自带的能力。你可能会想,容器挂载卷的时候直接用 Windows 路径,比如D:\project,然后发现 Docker 完全认不出来。
正确写法是,在 Ubuntu 里先看看路径在 WSL 里的位置,然后挂载 WSL 路径。比如 Windows 的D:\project\web在 WSL 里通常是/mnt/d/project/web,那么命令应该是:
docker run -v /mnt/d/project/web:/app -w /app nginx:alpine不要试图写D:\project\web,Docker 的路径解析不会帮你转换。
另一个实际体验问题:挂载/mnt/c或/mnt/d下的大目录,读写速度明显比 Linux 原生目录慢,而且文件所有者会显示成奇怪的数字或 root。这是因为 9P 文件系统协议在跨系统读写时有性能损耗和权限模型差异。
我的建议是:日常开发的项目文件尽量放在 WSL 的 Linux 文件系统里,比如/home/你的用户名/project,然后挂载这个路径。只有需要读取 Windows 侧的资料时才去访问/mnt/c。这么做之后,编译速度、依赖安装速度都会有非常明显的提升。
5.3 端口占用导致 Docker Desktop 起不来
启动容器时最常见的报错是:
Bind for 0.0.0.0:8080 failed: port is already allocated意思是你要映射的宿主机端口被别人占了。排查方法很简单,在 Windows PowerShell 里执行:
netstat -ano | findstr :8080会看到一个进程 ID,打开任务管理器找到对应进程,结束掉,或者换一个宿主端口重新映射。比如:
docker run -d -p 8081:80 nginx:alpine如果 Docker Desktop 本身起不来,图标一直转或者直接闪退,先检查是不是端口被 Hyper-V 的保留端口占用,以及虚拟化是否开启。也可以看%LocalAppData%\Docker\log\host日志,里面会直接写失败原因。
另外还有一个容易忽略的地方:如果之前用 Hyper-V 后端跑过 Docker,里面有旧容器在运行,切到 WSL2 后端后可能会出现状态残留。这时候可以执行wsl --shutdown,把 Docker Desktop 彻底退出,再重新启动,一般能解决。
5.4 Ubuntu 里执行 docker 命令显示 command not found
如果你进入了 Ubuntu,输入docker提示command not found,别急着去安装 docker.io。大多数情况下不是你缺 Docker,而是 WSL Integration 没生效。
先回 Docker Desktop 的 Settings → Resources → WSL Integration 看一眼,确认你的发行版被勾选。改完设置后点 Apply & Restart,等 Docker 完全启动,再重新进入 Ubuntu。
还有一类情况:你的 Ubuntu 是用wsl --import导入的,Docker Desktop 扫描发行版时可能没识别到,列表里根本没出现。解法是退出 Docker Desktop,再重新打开,让它重新扫描。如果还是不出现,检查一下发行版的名字,有些导入时被改成了奇怪的名字,认不出来很正常。
应急情况下也可以手动把 Docker Desktop 的 CLI 目录加进 PATH:
export PATH="$PATH:/mnt/c/Program Files/Docker/Docker/resources/bin"但这只是临时方案,真正干净的解法还是让 WSL Integration 生效。如果你之前手欠装过 docker.io,先卸载:
sudo apt remove docker.io docker-ce docker-ce-cli containerd卸载完再执行docker version,看到 Server 信息就说明集成已经恢复了。
6. 日常联动开发的一点体会
整套装好之后,我实际使用的场景基本是:Windows 桌面保留浏览器和 IDE,编码在 VSCode 里打开 WSL 的 Ubuntu 环境,需要跑中间件时用 Docker 容器,数据盘和项目代码都放在 WSL 文件系统里。这套组合用了一年多,非常稳定。
6.1 用 VSCode 打开 WSL Ubuntu,再操作 Docker 最顺手
VSCode 装一个 WSL 扩展,然后按 F1 输入 “WSL: Connect to WSL”,选择 Ubuntu,VSCode 就会以远程窗口的方式连到 WSL 环境。此时底部的集成终端自动就是 Ubuntu 的 bash,直接敲 docker 命令,代码目录也站在 Linux 文件系统视角。
好处是路径不会乱。你在 VSCode 里打开/home/用户名/project,终端里挂载卷也写这个路径,Docker 容器、代码编辑、命令行三者路径完全统一,不用来回换算 Windows 路径和 WSL 路径。我遇到的大部分“路径找不到”问题,在切换到这套工作流后就消失了。
6.2 磁盘和资源怎么规划:别把容器当虚拟机滥用
WSL2 默认内存使用策略是“最多拿宿主机一半内存”,看似大方,实际开发时容易把系统拖卡。你可以自己限制,在 Windows 用户目录下创建.wslconfig文件:
[wsl2] memory=6GB processors=4 swap=2GB改完执行wsl --shutdown再重新进入就会生效。这个文件对 Docker Desktop 的 docker-desktop 发行版同样生效,能避免容器任务和 Windows 桌面抢内存。
磁盘方面,镜像和容器数据都存放在docker-desktop-data这个 WSL 发行版的 vhdx 里,随着使用会越来越大。如果你经常拉镜像,偶尔要清理一下不用的镜像和容器。命令很简单:
docker system prune这条会把所有停止的容器、悬空镜像、无用网络缓存清掉,磁盘能释放不少。
6.3 我的最终建议:稳定渠道 + 持续更新
装环境这件事,第一次最好不要追求“三分钟”,按流程稳扎稳打反而最快。如果前面步骤已经具备,后面重装或者换机器就是纯粹的“下载安装包 + 设置集成”,那时你就会觉得三分钟不是夸张。
日常使用时,Docker Desktop 和 WSL 内核都建议保持更新。Docker Desktop 用 stable 渠道就够了,预览版虽然能提前体验新功能,但偶尔会引入后端问题,影响开发就得不偿失。WSL 内核用wsl --update保持最新,能避开那些“需要更新内核”的兼容性问题。
最后说一个很实用的小经验:如果哪天 Docker Desktop 突然连不上,先不要卸载重装。多半是后端状态卡住了,执行一次wsl --shutdown,然后重启 Docker Desktop,大概率直接恢复。这套流程我在无数台机器上试过,比折腾重装省心太多。