
Docker Desktop 的安装包双击下去一路点下一步最后托盘里冒出那条小鲸鱼——不少人以为这就装完了。等真正敲下第一条docker run画面卡在 pulling 上半天不动或者干脆甩一句 WSL kernel version too old才知道刚才那几分钟只是走了个过场。在 Windows 上部署 Docker麻烦的从来不是安装本身而是它底下那层虚拟化底座有没有铺好、资源划得合不合理、路径挂载对不对得上。这篇就按我这几年的实际折腾顺序从底层选型讲到日常维护把 Windows 上跑 Docker 这件事拆开揉碎说清楚适合刚上手的同学照着做也适合装过但老是出毛病的人回头对一遍。1. 装之前先搞清楚Windows 上的 Docker 到底跑在什么之上1.1 三种运行模式的本质区别很多人脑子里有个默认印象觉得 Docker 是个装在 Windows 上的普通软件跟装个压缩工具没区别。实际上 Windows 上的 Docker 从来不是原生跑的容器里的进程终究要落在某层虚拟化上。这一点想不明白后面所有报错都会变成玄学。目前主流就三条路。第一条是 Docker Desktop WSL2 后端也是现在官方默认推荐的路线Docker 引擎跑在一个轻量级的 Linux 虚拟机里这个虚拟机由 WSL2 提供你在 PowerShell 里敲的 docker 命令是通过命名管道转发进去的。第二条是老一点的 Hyper-V 后端Docker 自己拉起一台 LinuxKit 虚拟机跟 WSL2 是平级的两种方案。第三条是 Windows 容器模式跑的是基于 Windows 内核的容器镜像动辄几个 G生态也窄得多日常开发基本用不上。这三条路的差别不在于能不能跑而在于启动速度、内存占用、文件系统互通程度。WSL2 后端冷启动通常几秒钟Hyper-V 后端要慢一截WSL2 的 Linux 根文件系统是真实 ext4跑数据库这类吃 IO 的容器明显更稳而 Windows 容器模式连 basic 镜像都得拉好久。你如果只是本地跑个 MySQL、Redis、Nginx 验证业务逻辑闭眼选 WSL2 就对了。1.2 为什么默认推荐 WSL2 而不是 Hyper-VWSL2 胜出的核心原因在于文件系统层的设计。Hyper-V 后端下你把 Windows 的代码目录挂进容器走的是 SMB 那一套读一个几万文件的前端项目能卡到怀疑人生。WSL2 虽然跨系统访问也有损耗但它的 Linux 侧的/home目录是实打实的 ext4把项目放进去再挂载热更新速度能差出好几倍。还有一个容易被忽略的点是内存回收。Hyper-V 后端那台虚拟机一旦把内存吃上去Windows 侧不一定能及时要回来时间一长整机就开始发沉。WSL2 的虚拟机虽然也会膨胀这个我后面单独讲怎么治但至少有一个.wslconfig能从外部给它划死上限可控性强不少。我个人的判断标准很简单只要能开 WSL2就别碰 Hyper-V 后端。除非你处在某些限制比较死的公司电脑环境里WSL2 用不了那才退而求其次。这条经验在帮别人排查问题时屡试不爽——十个容器跑起来特别慢的案例七八个都是后端用错了。2. 装之前的硬性检查这几项不过关后面全是白折腾2.1 虚拟化开关与系统版本的对号入座安装之前先花两分钟做三项体检比事后折腾半小时管用。第一项打开任务管理器切到性能标签页点 CPU右下角会显示虚拟化已启用或已禁用。如果显示已禁用别急着装先去 BIOS 里把虚拟化打开不同主板叫法不一样常见的是 VT-x、SVM、AMD-V、Virtualization Technology 这几种说法通常在 Advanced 或者 CPU Configuration 子菜单下。第二项确认系统版本。WSL2 要求 Windows 10 版本 2004 及以上或者 Windows 11 任意版本。按 WinR 输入winver就能看到具体版本号。版本太老的话先升级系统别想着绕过去后面一定会出问题。第三项看看有没有装过旧版本的 Docker Toolbox 或者远古的 Docker for Windows。这类残留会占用命名管道和端口新版本装上去可能起不来。控制面板里翻一遍有就卸干净顺便把用户目录下的.docker文件夹也清掉。2.2 WSL2 的安装顺序与内核更新如果你用的是比较新的 Windows 11一条命令就够以管理员身份打开 PowerShell敲wsl --install它会自动帮你开启虚拟机平台功能、下载 WSL 和默认的 Linux 发行版。跑完重启一次开机后会自动弹出一个窗口让你设用户名密码。老一点的 Windows 10 需要手动两步。先启用两个可选功能dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart重启之后再把 WSL2 设为默认版本wsl --set-default-version 2。这一步很容易漏漏了的话新装的发行版还是跑在 WSL1 上Docker 后端会提示不兼容。内核更新包这个环节值得单独说一句。有些机器重启完wsl --status显示的版本号特别老这时候需要单独装一次 WSL2 的 Linux 内核更新补丁或者直接wsl --update让它自己下。我遇到过一台机器系统自动更新关掉了内核补丁怎么都装不上最后是手动下载 msi 包双击解决的。所以如果wsl --status报错别慌先看看内核这行。2.3 Windows 家庭版与公司电脑的绕行方案家庭版没有 Hyper-V这是很多人卡住的地方。但好消息是Docker Desktop 走 WSL2 后端并不需要 Hyper-V 完整功能只需要虚拟机平台这一项。所以家庭版照样能装安装 Docker Desktop 时会提示你走 WSL2 分支点同意就行别被那句需要 Hyper-V吓退。公司电脑的坑更隐蔽一些。有些环境开了组策略普通用户没有管理员权限改不了可选功能还有些装了终端安全软件会把新建的网络适配器当成异常行为拦下来。这类情况我的建议是先找 IT 确认能不能开虚拟机平台如果不能就老老实实申请一台开发机或者用远程容器环境别想着在限制机器上硬来装上了也三天两头出故障。另外提一句Windows 上那套\\wsl$的访问路径在某些网络驱动器映射场景下会失效如果你打算把项目放在网络盘上再挂载进容器基本可以放弃这个念头性能会很糟糕。3. Docker Desktop 的安装与首启动配置3.1 安装向导里的几个勾选项该不该取消拿到安装包之后默认路径是 C 盘如果 C 盘空间紧张可以在安装时改到别的盘但要注意这里改的只是程序本身的位置镜像和数据默认还是落在 C 盘后面单独讲怎么挪。安装向导里有个勾选项是Use WSL 2 instead of Hyper-V默认是勾上的保持就好。还有一个是Add shortcut to desktop纯个人喜好。倒是有一项要注意安装完成后它会提示你注销重新登录让当前用户加入 docker-users 用户组。这一步别跳过跳过之后你会遇到经典的 permission denied while trying to connect to the Docker daemon socket很多人以为是权限配置出问题其实就是没重新登录。装完第一次启动会跳出服务条款和可选的数据收集提示。服务条款得接受数据收集那项看你自己的接受程度不影响功能。之后它会做一次初始化可能要一两分钟别以为卡死了去强杀进程强杀之后残留的配置会让下次启动更麻烦。3.2 设置面板里真正需要改的只有几项打开设置面板一堆选项看着吓人实际需要动的就几处。第一处是 Resources 里的 CPU 和内存分配。默认值通常给得比较保守比如 2 核 2G跑个 Node 项目编译就喘。我的经验是给到物理内存的一半左右比如 16G 的机器给 8G核心数给一半或者略少。给太多也不行Windows 侧自己就没得用了切个浏览器都卡。第二处是 WSL Integration。这里会列出你装过的所有 Linux 发行版把你常用的那个开关打开这样在那个发行版的终端里也能直接敲 docker 命令不用每次都切回 PowerShell。这个功能太方便了尤其做前端的时候直接在 Ubuntu 终端里跑 npm 和 docker路径问题少一半。第三处是 Disk image location镜像存储位置。默认在C:\Users\你的用户名\AppData\Local\Docker\wsl这个目录会随着你拉镜像、建容器一路膨胀几十个 G 很常见。后面单独一节讲迁移。还有一处值得改的是 Docker Engine 的配置如果拉镜像速度慢可以在这里加一个镜像加速地址。注意写法是 JSON加完之后点 Apply Restart 让它生效格式写错会导致 Docker 起不来改之前最好把原内容复制一份留着。{ registry-mirrors: [https://你的加速地址] }3.3 把镜像存储挪出系统盘C 盘告急是 Windows 用户的通病而 Docker 又是那种默默吃掉几十 G 的软件。迁移方式在设置面板里就有Resources 下面的 Advanced 里有个 Browse 按钮选一个新目录点 Apply它会提示你重启 Docker 并自动搬过去。这个过程可能要几分钟取决于你已有的数据量期间别断电别强退。如果设置面板里搬不动还有个更土但更稳的办法先wsl --shutdown把虚拟机停掉然后用wsl --export docker-desktop-data D:\docker-data.tar导出注销原来那个发行版再用wsl --import导到新位置。这套操作风险高一点路径写错容易把数据弄丢所以我一般优先用面板里的功能。搬完之后建议顺手在设置里开一个清理提醒或者自己养个习惯每个月跑一次docker system df看看占用。这个命令会告诉你镜像、容器、卷、构建缓存各占多少比瞎猜准得多。4. 跑通验证从 hello-world 到真正能干活的环境4.1 三层验证引擎、网络、挂载装完之后别急着上项目按三层递进验证出问题好定位。第一层引擎是否活着。敲docker version正常会输出 Client 和 Server 两段信息。如果只有 Client 没有 Server说明引擎没起来去看托盘图标是不是红的或者执行wsl -l -v看 docker-desktop 这个发行版状态是不是 Running。第二层网络和镜像拉取。docker run hello-world是最经典的验证能打印出那段欢迎语就说明拉取、解压、运行链路全通了。如果卡在 pulling 很久基本是网络问题回到上一节配镜像加速。第三层挂载和端口。这一步最容易被跳过但恰恰是后面出问题最多的地方。开一个 nginx 试试docker run -d --name web -p 8080:80 nginx浏览器访问localhost:8080能看到欢迎页就说明端口映射正常。再验证挂载docker run --rm -v ${PWD}:/app alpine ls /appPowerShell 里用${PWD}cmd 里用%cd%Git Bash 里则要注意路径转换必要时在前面加MSYS_NO_PATHCONV1。这个差异坑过我不止一次同一行命令换个终端就报路径不存在。4.2 用 compose 起一组服务才算毕业单容器跑通只是入门真实项目一般要几个服务配合。写个最简单的docker-compose.yml起一个 web 加一个 redisservices: web: image: nginx ports: - 8080:80 depends_on: - cache cache: image: redis:7-alpine在当前目录执行docker compose up -d注意新版是docker compose中间是空格不是老的docker-compose然后用docker compose ps看状态docker compose logs -f看日志。全部 Up 之后再docker compose down收工。这一步的意义在于验证 Docker 的编排能力和网络隔离。compose 会创建一个独立的 bridge 网络两个容器之间用服务名互相访问这也是实际项目里最常见的形态。如果这一步顺了说明你的环境已经能承接日常开发了。5. 踩坑记录Windows 上最容易栽的几个地方5.1 虚拟化冲突模拟器和虚拟机软件抢资源这条坑我踩得最狠。装了 Docker Desktop 之后某些安卓模拟器、老版本的虚拟机软件会启动失败反过来它们先占着虚拟化层Docker 也起不来。本质原因是 WSL2 和这些软件都要用同一套虚拟化能力互相不兼容。解决办法有两个方向。一是错峰使用不用模拟器的时候彻底退出不留在托盘里。二是把模拟器换成支持新虚拟化接口的版本或者干脆用手机真机调试。这事没有完美的技术方案只能做取舍。顺带说个排查技巧如果 Docker 突然起不来而前一天还好好的先想想最近装了什么软件。任务管理器里看一眼有没有可疑的虚拟化进程比一头扎进日志里翻要快得多。5.2 WSL2 的内存与磁盘无声膨胀WSL2 有个著名的行为内存只涨不跌。你编译一次大项目它把内存吃到 8G之后即使空闲也一直占着任务管理器里那个Vmmem进程能吓死人。磁盘同理删掉的镜像和容器不一定立刻释放空间虚拟磁盘文件只增不减。内存的问题靠.wslconfig解决后面细讲。磁盘的问题有两个手段一是定期在 Docker 里执行docker system prune -a把没用的镜像、停止的容器、悬空卷全清掉二是必要时手动压缩虚拟磁盘文件。wsl --shutdown diskpart # 在 diskpart 里依次执行 # select vdisk fileD:\Docker\ext4.vhdx # compact vdisk这个操作要谨慎路径必须写准写错了可能伤到别的虚拟磁盘。执行之前把 Docker 完全关掉wsl --shutdown一定要跑。我一般一个季度做一次能把虚拟磁盘从七八十 G 压回三四十 G。5.3 挂载路径、文件权限与换行符跨系统挂载是 Windows 上跑容器的重灾区。第一个问题是性能把 Windows 目录挂进容器文件多了访问会非常慢前端项目的 node_modules 尤其明显。我的做法是把代码放在 WSL 的/home下用 VS Code 的 Remote 功能直接在里面编辑这样挂载路径就是 Linux 原生路径速度正常。第二个问题是权限。Windows 挂载进去的文件默认是 777 或者 root 所属跑一些对权限敏感的服务比如 SSH、某些数据库会直接报错。可以在 compose 里指定user或者干脆把数据卷单独建一个 volume 而不是 bind mount。第三个是换行符。Windows 的 CRLF 进了 Linux 容器shell 脚本会报bad interpreter: /bin/bash^M。解决办法是在项目里加.gitattributes强制*.sh text eollf编辑器里把默认换行符设成 LF。这个小问题能让新人卡一整天因为它报的错跟真正的原因毫无关联。5.4 端口占用与 localhost 的错觉-p 8080:80起不来报port is already allocated多半是本机已经有程序占了 8080。Windows 上查端口用netstat -ano | findstr :8080拿到 PID 再去任务管理器里对。有些系统服务会长期霸占特定端口比如某些版本里 5000 端口被系统占了你就得换个映射。另一个常见错觉是关于 localhost。大部分情况下容器跑起来浏览器访问localhost:端口是通的因为 Docker Desktop 做了转发。但如果 WSL2 那边网络模式改了或者本机装了某些防火墙这条转发链可能断掉。这时候可以在 WSL 里用hostname -I拿到虚拟机 IP用那个 IP 访问试试能通就说明是转发配置的问题。6. 长期维护让这套环境半年后还不卡6.1 用 .wslconfig 给虚拟机划上限这个是治内存膨胀的正方子。在用户目录下建一个.wslconfig文件路径是C:\Users\用户名\.wslconfig注意文件名前面有个点内容大概长这样[wsl2] memory8GB processors4 swap2GB localhostForwardingtrue改完必须执行wsl --shutdown让它彻底重启才生效光关 Docker 没用。这个配置是全局的对所有 WSL 发行版都起作用。内存值建议按物理内存的 50% 到 60% 给给太少容器会 OOM给太多 Windows 侧吃紧。有个细节值得注意swap 别设得太大。有些人为了防 OOM 把 swap 设成 8G结果磁盘狂转系统卡得像幻灯片还不如让它老老实实报内存不足然后你去调配置。6.2 定期清理与数据备份的正确姿势清理这块docker system prune是最常用的但它只清停止的容器、未使用的网络和悬空镜像。要连没被引用的镜像一起清得加-a。构建缓存单独用docker builder prune。备份的关键是数据卷。命名卷里的数据不会因为你删容器就消失但也容易忘。备份方式起一个临时容器把卷打包出来docker run --rm -v mydata:/data -v ${PWD}:/backup alpine tar czf /backup/mydata.tar.gz -C /data .镜像想导出的话用docker save -o app.tar 镜像名:标签换台机器docker load -i app.tar就能还原。这套操作在没有外网的机器之间搬东西特别有用。另外提醒一句别把重要的数据库数据只存在容器里。容器本质上是一次性的改配置、升级版本时删掉重建是常态数据必须落在卷或者宿主机目录上这是底线。6.3 和编辑器、终端的配合方式最后说说日常体验。VS Code 装个 Dev Containers 扩展可以直接把项目定义在一个容器里开发环境依赖写进配置文件换台机器一键还原这个对团队协作帮助很大。Windows Terminal 里配一个 WSL 的配置文件默认打开就是 Linux 终端敲 docker 命令跟原生一样顺。还有个习惯我保持了挺久把常用的 compose 命令写成脚本或者 alias比如dcu对应docker compose up -ddcl对应docker compose logs -f。Windows 上可以写在 PowerShell 的 profile 里也可以装个轻量的命令别名工具。这些小优化单看没什么积累下来一天能省不少敲键盘的时间。我个人在实际操作中的体会是Windows 上跑 Docker 这件事七分靠前置准备三分靠后续维护。装之前把虚拟化、系统版本、WSL2 内核这三关过了后面基本一路顺装完之后养成定期看docker system df、定期wsl --shutdown的习惯机器就不会越用越沉。真正难受的场景往往不是技术本身而是环境限制——公司电脑没权限、老机器开不了虚拟化、C 盘实在腾不出空间这类问题提前想好绕行方案比装完再返工省心得多。