ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Docker Desktop 安装后把 WSL2 虚拟磁盘和镜像存储迁出 C 盘的完整攻略

Docker Desktop 安装后把 WSL2 虚拟磁盘和镜像存储迁出 C 盘的完整攻略 很多人在Windows上装Docker最头疼的其实不是安装过程而是装完之后C盘那点空间肉眼可见地往下掉。默认情况下Docker Desktop把WSL2的虚拟磁盘、镜像层、容器层全部塞在系统盘里用不了几天就十几个G甚至几十个G这对分区紧张的机器来说相当难受。我自己也在这个坑里折腾过好几回。早期用Docker时没有提前规划C盘在短短一个月内从剩余60G掉到只剩8G最后只能重装。后来换了思路在安装阶段就把Docker的存储位置完整迁移到其他盘之后不管怎么拉镜像、怎么跑容器C盘都稳如老狗。这篇就从头过一遍包含系统准备、Docker Desktop安装、WSL2分发版落盘、vhdx迁移、镜像存储目录重定向、Docker Compose持久化一条龙全部给你梳理清楚。1. 安装方案与整体思路拆解1.1 为什么默认安装会把C盘塞满Docker Desktop在Windows上的工作方式是建立在WSL2之上的。装好之后它会创建一个专用的WSL分发版通常叫docker-desktop所有的Docker镜像、容器文件系统、日志数据都存在这个分发版的虚拟磁盘文件里。关键问题在于WSL2的分发版默认落盘位置是用户目录下的AppData\Local\Packages也就是C盘。这个虚拟磁盘文件是动态增长的刚开始可能只有1G多但只要你开始拉镜像它就会一张张地膨胀。我实测过拉一个包含基础工具链的完整镜像组合之后那个vhdx文件能瞬间从2G涨到12G而这还只是日常操作不是极端场景。docker-desktop目录如果不单独处理只会越滚越大。有些人觉得删镜像、清理缓存能缓解实际上镜像在Docker内部走的是分层存储删除镜像未必能及时压缩虚拟磁盘文件空间仍然被占着。所以最可靠的办法就是在装之前和装之后把存储路径彻底引到其他分区。1.2 两个落盘思路安装前重定向与安装后迁移处理“安装到其他盘”这个问题有两个时间点可以动手。第一个时间点是安装前在Windows功能里先装好WSL2用wsl --install -d Ubuntu命令提前指定一个非系统盘作为分发版的安装目录。这样后续Docker Desktop创建docker-desktop分发版时理论上就有了一个非C盘的参照不过Docker Desktop自身那个distro仍然不受你控制还需要后面再改。第二个时间点是安装后这时候系统里已经存在docker-desktop的vhdx文件我们可以用wsl --manage命令把整个分发版移动到目标盘。这个过程是微软官方支持的操作得当不会丢数据而且迁移之后Docker Desktop仍能正常启动。我最终采用的是先装系统组件、再装Docker Desktop、最后做两次迁移的组合方案。一次把docker-desktop主分发版移走一次把docker-desktop-data老版本或新的数据distro移走视版本而定。整个过程不需要第三方工具PowerShell和wsl命令就够了。1.3 方案对比为何不推荐修改镜像路径的“偏方”网上有些文章说改Docker Desktop设置里的Disk image location就能解决直接把虚拟磁盘位置指到D盘好像一劳永逸。这个做法在部分版本里确实有效Docker Desktop在设置面板里也提供了这个选项点一下Apply Restart就能迁移。但我实测发现这个选项并不是所有版本都稳定有时设置完看起来路径变了实际vhdx没动重启后又弹回默认路径。另外这个设置只作用于Docker自己的数据盘WSL2主分发版docker-desktop的存储位置完全不受它控制。所以我的建议是不要把设置面板里的路径选项当成唯一手段把它和wsl命令行迁移配合起来用。两条腿走路才能保证系统盘上不留死角。2. 系统准备与前置检查2.1 Windows版本和虚拟化支持检查动手之前先确认你的Windows版本。Docker Desktop要求Windows 10 64位专业版/企业版/教育版或Windows 11家庭版虽然能装但走Hyper-V或WSL2的路子会受限建议至少升级到专业版级别。确认版本之后检查CPU虚拟化是否已经开启。最直接的方法是打开任务管理器切到“性能”标签看CPU那一栏底部有没有“虚拟化已启用”。如果是“已禁用”需要进BIOS把Intel VT-xIntel处理器或AMD-VAMD处理器打开不同品牌主板位置不一样但基本都在Advanced或Security菜单下。还有一个小陷阱如果检测到“Virtualization support not detected”不一定真是BIOS没开也可能是主板固件里虚拟化开关和Windows Hypervisor共存出了问题。这种情况我后文排查部分再细说。2.2 开启WSL2与Virtual Machine Platform在PowerShell里依次执行下面两条命令把WSL和虚拟机平台组件打开dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart执行完需要重启。这里注意两条命令最好都加上/norestart让系统一次重启完成所有组件初始化省得连续重启两次。重启之后把WSL默认版本设为2wsl --set-default-version 2如果这里报错说不支持WSL2说明内核组件没装上。去微软官方文档下载WSL2 Linux内核更新包安装一遍再重试。2.3 检查并更新WSL内核WSL2不是装完就完事的内核是独立组件Docker Desktop在某些旧版本上会因为这个启动失败。保险起见升级到最新的WSL版本wsl --update这个命令会从微软服务器拉取最新的WSL内核期间不要中断网络。更新完确认一下版本wsl --versionWSL版本号大于等于1.0.0就算正常低于这个数字建议多执行几次更新直到内核和用户态组件都对齐。2.4 安装一个辅助用Linux发行版可选但推荐Docker Desktop本身会创建自己的WSL分发版但你额外装一个Ubuntu或者其他发行版对后面的路径管理和文件访问会方便很多。毕竟很多时候你想进容器宿主机看数据目录有一个常规Linux环境比Windows CMD里捣鼓wsl命令更直观。安装命令wsl --install -d Ubuntu这里有个诀窍可以顺便把安装目录指定到其他盘wsl --install -d Ubuntu --location D:\WSLDistros指定了--location参数Ubuntu的vhdx文件就会直接落在D盘从源头给系统盘省下一块空间。这个参数在较新的WSL版本里才支持如果你的版本不支持就装完再手动迁移。3. Docker Desktop 安装与基础配置3.1 下载安装包与安装流程去Docker官网下载Docker Desktop Installer.exe。下载的时候没什么讲究认准官方域名就行。双击安装包一路Next。到配置选项界面时建议不要勾选“Start Docker Desktop when you login”开机自启这货开机自启除了占用内存对你平常开发没太大意义需要时再点图标启动效率更高。还有一个选项是关于快捷方式的默认勾选就行。安装完成后会提示需要注销或重启选择“Restart later”先别重启因为接下来还要改配置。3.2 启动前检查Docker服务状态重启之后桌面会有Docker Desktop图标双击启动。第一次启动会比想象中慢因为要初始化WSL2后端环境。如果启动后右下角图标一直是鲸鱼翻滚动画等一会儿就好。如果几分钟过去还是老样子打开PowerShell检查wsl --list --verbose正常情况下能看到两个名称里带docker的分发版状态是Running或Stopped。如果这里显示的是Stopped手动启动wsl -d docker-desktop wsl -d docker-desktop-data这里有个关键点docker-desktop-data在较新版Docker Desktop里可能不存在新版把数据整合进了docker-desktop。所以不管看到的是一个还是两个docker相关的主机不用慌路径不对的地方最后统一处理。3.3 设置界面先关闭不需要的选项Docker Desktop右上角齿轮进入Settings有几个地方需要改。在General标签下确认“Use the WSL 2 based engine”是勾选状态。如果这个没勾Docker Desktop会尝试用Hyper-V但跟WSL2方案冲突后面容易出现failed to connect to the docker api的报错。在Resources标签下把WSL Integration里的Ubuntu就是你装的那个发行版打开这样在Ubuntu终端里也能直接用docker命令。在Docker Engine标签下暂时不需要动等后面要调整镜像加速或注册表配置时再改。网络代理那部分先别碰除非你知道自己公司网络环境的实际情况否则乱填代理地址会让Docker Desktop连不上docker hub反过来折腾你半天。4. 核心环节把Docker的存储迁移到其他盘4.1 第一步关闭Docker Desktop迁移vhdx文件之前必须保证Docker Desktop完全退出否则文件被占用wsl命令会直接报错。右键托盘里的Docker图标选择Quit Docker Desktop然后在任务管理器里确认没有残留的Docker Desktop进程。这一步别偷懒。有次我没退出干净就直接迁移wsl返回“process cannot access the file because it is being used by another process”我花了十分钟排查才发现是残留进程占着文件句柄。4.2 第二步确认当前vhdx文件位置打开PowerShell执行wsl --list --verbose然后查看当前分发版安装路径需要用注册表Get-ItemProperty HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss\* | Select-Object DistributionName, BasePath记下输出结果。典型的结构是这样分发版名称BasePathdocker-desktopC:\Users\你的用户名\AppData\Local\Docker\wsl\distrodocker-desktop-dataC:\Users\你的用户名\AppData\Local\Docker\wsl\dataUbuntuC:\Users\你的用户名\AppData\Local\Packages\...看到没有中间那个路径在C盘用户目录这就是我们需要搬走的主要对象。4.3 第三步导出并导入分发版传统迁移法迁移动作的核心是“导出-注销-导入”三连。导出的格式是tar包含整个分发版的文件系统。先建一个目标目录比如New-Item -ItemType Directory -Force -Path D:\DockerData\WSL然后导出docker-desktopwsl --export docker-desktop D:\DockerData\WSL\docker-desktop-backup.tar导出过程可能持续几分钟屏幕没有进度条完全靠耐心等。结束后注销原有分发版wsl --unregister docker-desktop注意unregister会删除原vhdx文件这就是为什么必须先导出。之后把导出的镜像导入到新位置wsl --import docker-desktop D:\DockerData\WSL\docker-desktop D:\DockerData\WSL\docker-desktop-backup.tar --version 2这里的语法是wsl --import 分发版名 落盘目录 镜像文件 --version 2。第三个参数跟第二个不一样第二个是你希望vhdx落地的地方第三个是刚才导出的tar镜像路径。docker-desktop-data同理wsl --export docker-desktop-data D:\DockerData\WSL\docker-desktop-data-backup.tar wsl --unregister docker-desktop-data wsl --import docker-desktop-data D:\DockerData\WSL\docker-desktop-data D:\DockerData\WSL\docker-desktop-data-backup.tar --version 2如果系统中没有docker-desktop-data只做docker-desktop一个就行。4.4 第四步使用wsl --manage迁移推荐方式老式导出导入流程能用但两个坑比较明显。一个是tar导出会包含所有镜像层文件特别大导出再导入整个流程耗时很长另一个是导入后某些文件属性和路径映射会变化偶尔会导致Docker内部权限异常。更现代的办法是用wsl --managewsl --manage docker-desktop --move D:\DockerData\WSL\docker-desktop这个命令直接在WSL层完成vhdx文件搬迁不需要导出tar速度比导出导入快好几倍也不改变分发版内部文件系统结构。实测一个10G左右的docker-desktop vhdx移动过程大约30秒而导出导入法要跑差不多五分钟。如果你的WSL版本支持--manage优先用它。检查方法很简单执行wsl --manage --help如果命令存在就能用。4.5 第五步验证迁移结果并确认默认启动迁移完成后执行wsl --list --verbose确认docker相关分发版都在列表里然后重新看注册表BasePathGet-ItemProperty HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss\* | Select-Object DistributionName, BasePathBasePath应该指向D盘的对应目录。现在已经完成了一大半。接着启动Docker Desktop等右下角鲸鱼图标稳定下来。打开PowerShell执行docker version确认客户端和服务端都正常输出。这里有一步不能省在Docker Desktop里拉一个小镜像验证整个链路通不通。docker run hello-world输出“Hello from Docker!”就说明服务正常。5. 追加优化镜像存储目录与Compose持久化5.1 把Docker镜像存储目录彻底改到其他盘如果你用的是较新版本Docker Desktop单纯迁移WSL分发版之后镜像数据已经跟着vhdx走到了其他盘。不过还有一类存储路径不受WSL控制就是“Images”页签里Expose daemon on tcp以及Docker Engine配置里的data-root字段。打开Settings在Docker Engine的JSON配置里增加{ data-root: D:\\DockerData\\docker-root }保存并Apply Restart。此操作会把Docker守护进程的镜像层、容器层、volume数据全部改存到data-root指定的路径。注意路径必须使用双反斜杠或者正斜杠单反斜杠会被JSON转义解析出问题。如果设置后提示创建目录失败检查一下D盘是不是NTFS格式Docker对文件系统有要求FAT32会直接拒绝挂载。5.2 docker-compose 项目落盘与数据目录规划日常开发里docker compose是绕不开的。很多人的项目目录放在C盘容器里挂载的volume又指向项目目录结果迁移了半天Docker本身最终数据还是写回C盘。我的习惯是所有docker compose项目的根目录统一放在D盘比如D:\Projects\docker-services每个服务一个子目录里面放docker-compose.yml、.env、data挂载目录。举个例子一个常见MySQL容器配置version: 3.8 services: mysql80: image: mysql:8.0 container_name: mysql8 restart: always ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: your_root_password volumes: - D:\\DockerData\\mysql80\\conf:/etc/mysql/conf.d - D:\\DockerData\\mysql80\\data:/var/lib/mysql这样配置之后MySQL的数据文件、配置文件全部落在D:\DockerData\mysql80下面跟C盘没有任何关系。5.3 设置镜像加速与私有镜像仓库地址国内网络环境下拉取Docker Hub官方镜像经常比较慢或者直接超时。在Docker Engine JSON的data-root下面加一行registry-mirrors{ data-root: D:\\DockerData\\docker-root, registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com ] }配置完保存并重启拉镜像速度会明显改善。如果公司内部有私有镜像仓库还要在insecure-registries字段里加入内网仓库地址同样写在JSON里。注意生产环境如果走HTTPS需要用certs配置不要直接把insecure-registries当成万能药。5.4 定期检查空间增长并清理无用镜像迁移完成之后不代表永远不用管。vhdx文件是动态增长的即使所有存储都在D盘也建议定期检查一下docker system df这个命令会显示镜像、容器、volume、build cache各自占用的空间。对长期不用的容器和镜像执行docker system prune -a这条命令会清理所有停止的容器、未被任何容器引用的镜像、未使用的网络和build cache。第一次执行它会问确认加-f可以跳过确认。还有一个小建议prune之后vhdx文件并不会立刻缩小因为虚拟磁盘只扩不缩。如果磁盘空间极度紧张可以每个月做一次wsl --shutdown然后对vhdx执行压缩后面在问题排查部分细说。6. 常见问题与排查技巧实录6.1 Docker Desktop 启动失败npipe连接失败报错信息通常是failed to connect to the docker api at npipe:////./pipe/dockerDesktopLinuxEngine这个报错九成的情况是Docker引擎没起来而不是你的网络有问题。排查顺序第一步检查WSL2后端是否正常wsl --list --verbose看到docker-desktop的STATE是Stopped先启动它wsl -d docker-desktop然后在wsl里执行service docker status如果服务没起就service docker start。这一步解决后回Windows启动Docker Desktop一般就能通了。如果服务起了还是连不上那就重启Docker Desktop。还不行就把Docker Desktop完全退出、wsl --shutdown之后重新启动。6.2 虚拟化检测失败Virtualization support not detected装Docker时提示虚拟化没检测到但BIOS里明明开启了这种诡异情况我也遇过。先检查Hyper-V和虚拟机监控程序是否被其他软件抢占。名侦探工具是系统信息在PowerShell执行systeminfo看Hyper-V要求那一行如果显示“检测到虚拟机监控程序。将不显示Hyper-V所需的功能。”说明虚拟化层已被其他组件占用Docker Desktop可能检测不到VT-x但不影响实际运行。这时可以试试用管理员身份执行bcdedit /set hypervisorlaunchtype auto然后重启。这个命令会让Windows引导时加载Hyper-V hypervisor为WSL2提供底层的虚拟机监控能力。6.3 WSL导入后Docker数据目录不生效迁移完分发版Docker Desktop能启动但镜像数据仍然在旧路径或者新建镜像时发现存储空间还是算在C盘。这种情况一般是WSL Integration没生效。打开Docker Desktop设置在Resources - WSL Integration里确认你用的发行版开关是打开的然后点Apply Restart。还有一种可能你同时有多个发行版Docker Desktop默认只启用一个而导出的那个并不是当前启用的。在设置里把目标发行版的开关打开再拉一次镜像测试。6.4 移动后路径无法创建目录或权限报错Docker创建目录时报类似“failed to mkdir ... permission denied”先看目标文件夹是不是只读属性。右键D:\DockerData - 属性 - 安全确认当前用户有完全控制权限。实在不行把该目录的继承权限重置一下。右键 - 属性 - 安全 - 高级 - 更改权限勾选“使用可从此对象继承的权限替换所有子对象的权限”应用后重试。6.5 定期压缩vhdx文件回收空间Docker长期使用后即使删了很多镜像D盘上的vhdx文件也不会自动收缩因为ext4文件系统内的空闲块不会自动归还给Windows虚拟磁盘。这时候需要手动压缩。先关闭Docker Desktop然后wsl --shutdown管理员权限打开PowerShell进入目标目录cd D:\DockerData\WSL\docker-desktop使用diskpart压缩vhdxdiskpart select vdisk fileD:\DockerData\WSL\docker-desktop\ext4.vhdx attach vdisk readonly compact vdisk detach vdisk exit这个操作能把vhdx压缩到接近实际使用量。我实测一个显示35G的vhdx压缩后只有11G效果极其明显。这个流程建议每个月跑一次养成习惯后系统盘和D盘空间都不会失控。6.6 Docker Desktop 与公司代理环境冲突在公司网络里装Docker经常遇到镜像拉不下来的问题。先分清是网络代理问题还是镜像源问题。如果docker pull时提示“unable to retrieve image”而且公司统一有代理那么要在Docker Engine JSON里配置代理。但这里有个坑Docker Desktop设置的代理只是给Docker引擎用的容器内部的流量不走它。容器里如果需要访问外网得在容器运行环境里单独配置HTTP_PROXY环境变量或者在docker-compose.yml里给服务加environment里的代理设置。如果不确定公司用的是什么网段别乱填代理。先试registry-mirrors加速源大部分情况能解决。7. 我的实操心得与日常使用建议迁移跑通只是第一步真正让Docker用着顺手还得养成几个习惯。第一把WSL2和Docker的存储空间当成一个整体来管理。Docker Desktop只是虚拟化层上的一个服务它消耗的是WSL分发的磁盘资源。所以每次清理Docker资源记得检查WSL磁盘占用不要只盯着docker system df。第二Docker Desktop的自动更新不会动你的vhdx路径这个放心。但更新后建议执行一次wsl --shutdown再启动让新版引擎和新内核组件对齐避免一些跑一两天后才出现的诡异问题。第三docker compose是长期使用的首选。别在命令行里瞎docker run环境变量、卷映射、端口配置全部写进yml项目从零起来也只敲一行docker compose up -d。路径规划从一开始就落在D盘项目名作为子目录以后拆机器、换电脑只需要把D盘对应目录整个拷走新环境重新docker compose up就能恢复。还有个小技巧迁移之后如果觉得Docker Desktop启动还是慢可以在D盘放一个快捷启动脚本每次用管理员权限打开自动执行wsl --shutdown清理残留然后启动Docker Desktop。这个脚本我用了半年没再遇过连不上引擎的故障。Docker装到其他盘这件事本质上不是技术活而是规划活。关键是动手之前把存储路径想清楚安装完马上迁移不要等到C盘告急才来救急。照着上面的流程走一遍你的C盘容量会一直保持在一个干净的状态Docker随便折腾都不心疼。
返回列表