Windows 上跑 Docker:选 Docker Desktop 还是 WSL2 原生引擎?
本文完全由 WorkBuddy 独立收集资料、调试代码并完成文章写作。
我是 Alex Xiang,前百度/微博工程师,现在专注于 AI 工程与工具产品。更多文章欢迎关注微信公众号「字与码」。
这个问题看起来一句话就能答完,但我在一次讨论里被连续追问了四轮,结论被推翻了两次。
第一轮的问题是:在 WSL2 下装 Docker,该用 Docker Engine 还是 Docker Desktop?
第二轮:想让里面的容器一直在线,是不是要有额外操作?比如单独起一个保活用的 WSL 实例?
第三轮:如果是对外提供 7×24 小时服务,必须用 Windows 机器,选哪个?
第四轮,也是真正把结论推翻的那一轮:这台机器是 Windows 家庭版。
约束每加一层,答案就换一次。把一个完整的判断链写下来,比直接给结论有用得多。
先分清两条路的架构
一个容易被忽略的前提:在 Windows 上跑 Linux 容器,不存在「不用虚拟机」这个选项。Windows 内核跑不了 Linux 容器,所以无论选哪条路,容器最终都跑在一个 Linux VM 里。
区别在于两件事:谁在管这个 VM,dockerd 住在哪。
Docker Desktop 的 WSL2 后端会创建属于它自己的发行版 —— 早期是 docker-desktop(跑 dockerd)和 docker-desktop-data(存镜像与数据),新版把两者合并了。你的 Ubuntu 只是被「接线」过去:Docker Desktop 往里面注入 docker CLI、/var/run/docker.sock 和几个环境变量,你自己的发行版里其实没有 dockerd。
而在 WSL2 里直接装 docker-ce 的方案,dockerd 就住在你自己的发行版里,由 systemd 管理。

这个架构差异派生出后面所有区别:资源占用、与生产环境的一致性、排障方式,以及两者能不能同时存在。
顺带说一个高频事故:这两条路不要同时装。Docker Desktop 会往你的发行版注入 CLI 和 socket 配置,和本地原本的 dockerd 抢 /var/run/docker.sock,报错信息完全看不出根因 —— 典型表现是连上一个空 socket,或者莫名其妙的 permission denied。要换路线就先把旧的卸干净:Desktop 卸载后记得清理它留下的发行版,原生方案则要 apt purge docker-ce docker-ce-cli containerd.io 并删掉 /etc/docker。
开发场景下,授权才是最大的变量
如果是自己开发用,技术差异其实都是次要的,最先要确认的是授权。
Docker Desktop 的订阅协议规定:员工少于 250 人 且 年收入低于 1000 万美元的公司,可以免费商用。注意这两个条件是「且」——跨过其中任意一条,每个打开 Docker Desktop 的人都得付费订阅。按年付口径,Pro 是每人每月 9 美元,Team 15 美元,Business 24 美元,而 Business 没有任何年付折扣。政府实体没有免费档,哪怕只有五个人。
Docker Engine 本身是 Apache 2.0,在 Linux VM 里装它没有任何限制。许可证约束的是 Docker Desktop 这个产品——那个 GUI、那个托管的 VM、它捆绑的 Compose v2 二进制。底层那些开源项目(Docker Engine、containerd、runc、BuildKit)都不在此限。
| 维度 | Docker Desktop(WSL2 后端) | WSL2 里装 docker-ce |
|---|---|---|
| 授权 | 个人、教育、开源免费;公司 ≥250 人或 ≥1000 万美元收入需付费 | Apache 2.0,任何规模免费 |
| 安装与运维 | 装完勾选 WSL 集成即可,自动更新 | 要开 systemd、手动 apt upgrade、自己配 daemon.json |
| 图形界面 | 有 Dashboard,可看容器、镜像、日志、资源曲线 | 无,纯命令行 |
| Kubernetes | 一键开单节点 | 自己搭 kind / k3d / minikube |
| Windows 侧可用 | 是,PowerShell 里直接 docker ps | 否,只能用 wsl docker ... |
| 资源开销 | 偏高,多一层 GUI 进程和托管 VM | 低,只有 dockerd 和容器进程 |
| 与生产一致性 | 隔了一层封装,docker info 与服务器不同 | 和线上 Linux 主机完全一致 |
一个容易被误解的点:授权是合同约束,不是技术拦截。超出免费范围之后 Docker Desktop 不会停止工作,但这件事会在收购尽调或 SOC 2 审计时浮现出来,而且 Docker 确实发过补缴账单。
所以开发场景的结论很清楚:个人、学习用途、未越线的小团队,用 Docker Desktop 省事;公司已越线、或者你在意合规风险,就在 WSL2 里装 docker-ce。
想让容器一直在线,先搞清它为什么会掉
第二个问题的答案是:必须做额外操作。而且原因很反直觉。
WSL2 有两道空闲超时,默认都开着:
instanceIdleTimeout,写在.wslconfig的[general]段,默认约 8 秒 —— 当实例里所有用户进程都结束后,多久关掉这个发行版vmIdleTimeout,写在[wsl2]段,默认 60000 毫秒 —— 当所有实例都停止后,多久销毁整个 WSL2 轻量 VM

换句话说:你关掉最后一个终端窗口,8 秒后发行版关闭,dockerd 被杀,容器全灭;再过 60 秒,整个 VM 也被销毁,内存归还给 Windows。
这里有个几乎所有人都会踩的误解:systemctl enable docker 保不了活。
它只解决了「实例启动时自动把 dockerd 拉起来」,没有解决两件更根本的事:开机后根本没人启动这个实例,以及实例自己在 8 秒后会关掉。systemd 管理的服务不算「用户进程」,WSL 该关还是关。有用户报告,启用 systemd 之后连一个独立的 tmux 会话都会被一起带走。
关于「另起一个保活用的 WSL 实例」这个思路,它不成立,而且方向反了。所有 WSL 发行版共享同一个轻量 VM,VM 被销毁时它们一起死,多开一个实例只是白吃一份内存。要保活的是那个共享 VM,不是在它里面加实例。
保活要过三道闸门
第一道,先让实例别自杀。在 Windows 用户目录下创建或编辑 .wslconfig:
[general]
instanceIdleTimeout=-1
[wsl2]
vmIdleTimeout=-1
memory=8GB
-1 表示永不自动关闭。改完必须执行 wsl --shutdown 才生效。顺带建议显式设 memory 上限 —— 默认 WSL 可以吃掉宿主机一半内存,常驻不退的话会一直占着。
第二道,让实例真的存在,并挂住一个常驻进程。WSL 不会开机自启,必须有人拉它。最直白的做法是用 Windows 计划任务挂一个不会结束的进程:
wsl.exe -d Ubuntu -u root -e sleep infinity
这个 wsl.exe 进程会一直挂着,实例就一直活着。
第三道,容器自己要有重启策略。docker run 时加 --restart=always,或者 compose 里写 restart: unless-stopped。后者的意思是「除非你手动停过,否则总拉起来」,做常驻服务时可控性更好。
还有个好消息:如果你用 Docker Desktop,这三道闸门基本不用你操心 —— 它是个 Windows 侧应用,开机自启后会自己拉起并维持 WSL 实例。但有个细节要知道:Resource Saver 在 WSL 上的行为和 Mac 不同。官方文档明确说,它只暂停 docker-desktop 发行版里的 Docker Engine,不会停 WSL VM,因为那个 Linux VM 是所有发行版共享的、不归 Docker 管。好消息是它的触发条件是「持续一段时间没有容器运行」(默认 5 分钟),所以只要有容器一直在跑,它就不会介入。
7×24 服务,关键变成谁在管那个 VM
到这里才是真正分岔的地方。开发场景下两条路差异不大,但一旦变成无人值守的对外服务,判断依据就换了:这个 VM 的生命周期由什么驱动。

三条路摆在一起看:
- Docker Desktop + Hyper-V 后端:由
com.docker.service这个 Windows 服务驱动,不依赖用户登录 - Docker Desktop + WSL2 后端:由
Docker Desktop.exe这个用户态应用驱动,依赖会话 - WSL2 原生引擎:由
wsl.exe会话驱动,依赖用户进程
后两条本质上都是在跟 WSL 的设计意图拔河。WSL 是个开发工具 —— 按需启动、空闲自杀、内存动态回收。你做的所有保活配置都是在对抗这个取向,而这种对抗在 Windows 更新之后容易失效。
所以如果必须二选一,选 Docker Desktop,前提是切到 Hyper-V 后端。这是三条路里唯一一条从 Windows 服务起步的。
这个切换有两个门槛。一是需要 all-users 安装模式(装到 C:\Program Files,要管理员权限),官方文档写得很明确:Hyper-V 只在 all-users 安装时可用,默认的 per-user 安装没有这个选项。二是需要专业版或更高 —— 家庭版没有 Hyper-V。另外补一句:Docker Desktop 官方不支持 Windows Server,2019 和 2022 都不行。
切过去之后,让它在无人登录的情况下启动,可以用官方的 headless 参数配合任务计划程序。注意要用「创建任务」而不是「创建基本任务」,触发器选「启动时」,勾选「使用最高权限运行」:
"C:\Program Files\Docker\Docker\Docker Desktop.exe" --headless
后面那串参数是官方提供的无界面运行方式,配合 S4U 登录类型可以在不把密码写到磁盘的前提下工作。
但更好的答案不是在两者里选
如果真实约束是「必须用 Windows 机器」,而不是「必须用 Docker Desktop」,那最优解其实是第三条路:
在 Hyper-V 里跑一个标准 Ubuntu Server VM,在 VM 里装 Docker Engine。Docker Desktop 和 WSL 都不用。
听起来更麻烦,但它一次解决了前面所有问题:
- 不依赖用户登录:VM 的「自动启动操作」设为「始终自动启动」,由 Hyper-V 主机服务在开机时拉起,不需要任何用户会话
- 网络干净:用外部虚拟交换机给 VM 分一个局域网固定 IP,对外服务不需要
netsh portproxy,Windows 重启也不影响 - 有检查点:升级出问题能回滚,这是 WSL 完全没有的能力
- 不牵扯 Docker Desktop 的授权
- 就是一个标准 Linux 服务器:现成的运维知识、脚本、systemd 配置、
journalctl排障流程全部可用
代价是内存要固定分配(WSL 是动态共享的),而且需要专业版以上。如果这台机器是专职跑服务的,这两点都不是问题。
如果只有 Windows 家庭版
这是最后一个被追加的约束,而它把前面给出的最优解直接推翻了。
家庭版缺的不只是一个 Hyper-V:
| 缺失的能力 | 对 7×24 服务的影响 |
|---|---|
| Hyper-V | 无法用「Hyper-V VM + Docker Engine」这条最优路径 |
| 组策略(gpedit.msc) | 无法长期推迟 Windows 更新,自动重启是无人值守服务的头号杀手 |
| 远程桌面主机 | 不能作为 RDP 目标,无人值守机器的运维通道要另想办法 |
| BitLocker 管理 | 只有简易设备加密,没有恢复密钥托管 |
最要命的是中间两条。家庭版没法长期推迟更新,只能用注册表(NoAutoRebootWithLoggedOnUsers、AUOptions)硬撑,而这些键在功能更新后可能被重置。而远程桌面主机这一条,意味着你得改用 SSH、RustDesk 或 VNC 之类的通道。
关于 Hyper-V:家庭版不能启用它。用 dism 强行打开也没用 —— 外部虚拟交换机、嵌套虚拟化、第二代虚拟机这些「只在专业版上正常工作」,在家庭版上要么组件缺失,要么服务看起来启动了但实际不工作。这不是技术能力问题,是微软在操作系统层面划的许可边界。
于是家庭版实际只剩 WSL2 一条路。第三方虚拟机(VirtualBox、VMware)算备选,但它们的 VM 注册同样是按用户的,一样绕不过登录问题,还要和 WSL2 抢虚拟化后端 —— 得关掉内存完整性才能跑全速。
在这条路上,我建议用原生 docker-ce 而不是 Docker Desktop:少一层桌面应用依赖,可预测性更好。无人值守服务里,可预测性比省事重要 —— Docker Desktop 那些「贴心」的自动化(自动更新、Resource Saver)在这个场景下全都变成不可控的变量。
还有个缺口必须说清楚:家庭版没有官方支持的无用户登录自启方案。
WSL 发行版注册在 HKCU\...\Lxss 注册表里,是按用户的。社区流传的用 SYSTEM 账户跑 wsl.exe 的做法(再配合 WSL 内的 loginctl enable-linger)有人成功,也有人稳定失败,典型报错是 return code 4294967295。这不是微软支持的路径。
稳的做法是配置 Windows 自动登录,再把保活挂在用户级计划任务上:触发器设「登录时」,再加一个每 2 分钟重复的巡检。代价很直白 —— 任何能物理接触这台机器的人,开机即进桌面。
顺带避一个坑:网上有回答给出 [wsl2] autostart=true 这个配置项,它根本不存在,别照抄。
结论
把四层约束的结论并排放在一起:
| 你的情况 | 该选什么 | 主要原因 |
|---|---|---|
| 个人开发、学习、未越线的小团队 | Docker Desktop(WSL2 后端) | 省事,省下的配置和排障时间超过那点内存开销 |
| 公司已越 250 人或 1000 万美元 | WSL2 原生 docker-ce | Apache 2.0 免费,避开授权审计风险 |
| 要贴近生产、要写 CI、要调 daemon | WSL2 原生 docker-ce | 与线上 Linux 主机完全一致 |
| 内存吃紧、讨厌常驻 GUI | WSL2 原生 docker-ce | 没有托管 VM 和托盘进程那层开销 |
| 必须 Windows、能做 7×24 服务、有专业版 | Hyper-V VM + Docker Engine | 唯一从系统服务起步的路径,还能配固定 IP |
| 必须 Windows、且想用 Desktop | Docker Desktop + Hyper-V 后端 | 三条路里唯一从 Windows 服务起步的 |
| Windows 家庭版 | WSL2 原生 docker-ce | Hyper-V 用不了,只剩这条路 |
最后说一句实在话。如果这个服务有「不能停」的语义,就不该让一台 Windows 桌面机成为唯一节点。桌面机硬件没有冗余,系统更新会强制重启,断电就是硬关机 —— 而 WSL 的 ext4.vhdx 在非正常关机后的损坏是有实证案例的:微软官方问答区就有人拿它跑生产站点的数据然后挂掉了,典型报错是 Error code: 74 Wsl/Service/CreateInstance/E_FAIL,VHDX 文件还在、大小正常,但死活挂不上,救援手段是 wsl --mount --vhd --bare 配合 e2fsck。
还有一件事无论选哪条路都值得做:别让业务数据只活在 VM 磁盘里。数据库的 volume 挂到 NTFS 分区,或者定期导出 dump,再加一个定期的 wsl --export 冷备份。这样即使 VM 磁盘出事,数据还在。
参数、有效期和定价都会变,动手前建议核对一下官方文档当期的说法。
参考资料
- Docker Desktop 在 Windows 上的安装与系统要求(含 WSL2 / Hyper-V / Docker VMM 三种后端的适用条件):https://docs.docker.com/desktop/setup/install/windows-install/
- WSL 高级设置配置参考(
.wslconfig全部可用键,含vmIdleTimeout):https://learn.microsoft.com/en-us/windows/wsl/wsl-config - Docker Desktop 的 Resource Saver 模式(含它在 WSL 上与其他平台的行为差异):https://docs.docker.com/desktop/use-desktop/resource-saver/
- Docker 订阅服务协议与定价:https://www.docker.com/pricing/
- 在无用户登录的情况下自启 WSL2 的社区讨论(含失败案例与报错码):https://github.com/microsoft/WSL/discussions/14261
微信公众号
欢迎关注「字与码」
如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。
X / Twitter
关注 @ax2_zicode
更即时的技术观察、新文章提醒和一些短想法会发在 X 上。