ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Windows下Docker Desktop安装到指定目录及WSL数据迁移指南

Windows下Docker Desktop安装到指定目录及WSL数据迁移指南 先交代一下背景。前阵子给实验室一台Windows 11机器装Docker Desktop跑了两天容器之后发现C盘被塞得只剩几个G。打开目录一看Docker程序本体、WSL虚拟磁盘、镜像数据全在C盘压根没给我选路径的机会。这个本地windows安装docker到指定目录的问题其实很典型官方安装器默认不提供图形化目录选择WSL2后端的数据存放位置又藏在用户目录底下很多人装完就后悔。这篇笔记把我这次折腾的完整过程记下来目标是搞清楚两个问题一是Docker Desktop程序本体怎么装到D盘二是真正吃空间的镜像和容器数据怎么迁出去。刚准备装的可以照做已经装完在收拾残局的也能找到对应方案。1. 安装前先搞清楚Docker在Windows上的运行机制1.1 Docker Desktop和WSL2到底是怎么配合的很多第一次在Windows上装Docker的朋友会有一个误解以为Docker Desktop就是一个普通的Windows服务装完开机自启就能跑。实际上Docker在Windows上分两条路线老一点的Hyper-V后端和现在主流的WSL2后端。WSL2后端下Docker引擎不是直接跑在Windows进程里而是跑在一个由WSL2管理的轻量级虚拟机中。这个虚拟机以发行版的形式注册在系统里Docker Desktop会自己创建一两个内部发行版比如常见的docker-desktop和docker-desktop-data。关键在于WSL2的每个发行版背后都是一个VHDX虚拟磁盘文件。镜像层、容器读写层、卷数据全部写在这个VHDX里。你可以把它理解成一台没有界面的小Linux电脑Docker的命令进去以后所有文件操作都发生在那个虚拟磁盘内部。这个文件默认放在当前用户目录下例如C:\Users\你的用户名\AppData\Local\Docker\wsl。所以不管你把Docker Desktop的程序装到哪个盘只要没处理这个VHDXC盘照样会慢慢被吃干净。明白这一点就理解了安装到指定目录为什么是个两层问题表层是程序安装目录深层是WSL数据目录。网上很多教程只解决了表层装完之后C盘还是越来越满就是因为漏了深层。1.2 为什么指定目录比想象中麻烦Docker Desktop的安装器有几个特点图形界面只有默认下一步没有让你选安装路径的步骤安装完后升级时可能还会往原路径写文件更麻烦的是WSL数据目录和程序目录没有联动关系单独搬程序目录解决不了空间问题。我这次踩的坑就是先装了默认路径等C盘告急才开始想办法。Windows上给已有软件搬家最忌讳直接改注册表或者把exe复制过去就完事。相比之下目录联接junction是一个很好的思路原理类似快捷方式但比快捷方式透明——程序以为文件还在原路径实际读写全部落到了新目录。不过这个方案要注意版本差异和权限问题后面详细说。如果你还没开始装强烈建议直接跳过先装再搬的弯路用命令行参数一步到位。如果你已经装完也别慌下文两种方案都给了。2. 动手之前的环境准备虚拟化、WSL2和磁盘规划2.1 第一步先确认CPU虚拟化已经开启Windows上跑WSL2或者Hyper-V都依赖CPU虚拟化。很多人装Docker报错virtualization support not detected十有八九是BIOS里虚拟化没开。检查方法很简单任务栏右键打开任务管理器切到性能页选中CPU右下角有一项虚拟化显示已启用就说明BIOS层面没问题。如果显示已禁用需要重启进BIOS开启。Intel平台通常叫Intel Virtualization Technology或者VT-xAMD平台常见叫SVM Mode。笔记本厂商不同选项位置差异很大普遍在Advanced、Configuration或者Security菜单下。这一步一定要装Docker之前确认好等装完再发现虚拟化被关排查起来很头疼。顺带补充一句如果你是老平台、Windows版本又比较旧还要确认CPU是否满足Docker Desktop的最低要求。官方要求64位、支持虚拟化的CPU这个绝大多数近十年的机器都满足。2.2 把WSL2启用并设为默认版本确认虚拟化开启后下一步是启用Windows的WSL2底层功能。在管理员权限的PowerShell或者CMD里执行以下命令dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart第一条启用Linux子系统功能第二条启用虚拟机平台两者都是WSL2必需的。执行完会提示重启重启之后再进入管理员终端把WSL默认版本设为2wsl --set-default-version 2如果你的系统比较新也可以用一条wsl --install直接搞定这个命令会自动安装WSL2并开启相关功能。实操中我更喜欢分开执行因为能看到每一步的状态出问题也知道卡在哪一步。需要留意的是有些老版本Windows在--set-default-version 2时会提示需要升级内核。这种情况去微软官网搜索WSL2 Linux kernel update下载安装对应更新包即可。这不是Docker的问题是WSL组件本身太老。2.3 给D盘预留空间C盘留出余量装之前先算一笔账。Docker Desktop程序本体大概占1.5到2GBWSL虚拟磁盘初始状态几百MB但只要你开始拉镜像膨胀速度会非常快。一个稍微完整点的开发环境镜像几个G很平常。我建议D盘至少预留20到30GB的富余否则迁完数据没多久又会遇到空间不足。C盘这边也要留出余量。WSL2的虚拟磁盘虽然搬到D盘但Windows本身运行时还会产生临时文件、Windows Update缓存等。给C盘留出至少10%到20%的空闲空间能让Docker运行稳定很多。另外VHDX文件有个特点删了镜像它也不会自动缩小只有主动压缩才会回收空间。这个问题放到后面讲先记着这个特性。3. 核心操作怎么把Docker Desktop装到指定目录3.1 全新安装最省事安装器命令行参数Docker Desktop的Windows安装器支持命令行参数这是官方支持的指定目录方式。先去Docker官网下载最新版安装包假设你把它放在D:\Downloads目录然后右键开始菜单打开Windows PowerShell管理员执行cd D:\Downloads .\Docker Desktop Installer.exe install --installation-dirD:\Docker --accept-license --backendwsl-2拆解一下参数--installation-dir指定程序安装目录--accept-license跳过许可协议交互--backendwsl-2指定后端类型。如果不想看安装进度可以再加一个--quiet让它静默执行。有一点要提醒不同版本的安装器参数有细微差别。老版本教程里出现过--install-dir这种写法而新版本通常用--installation-dir。保险起见可以先执行 .\Docker Desktop Installer.exe install --help看一下当前版本支持哪些参数再照着写。装完之后开始菜单会出现Docker Desktop图标首次启动会做WSL环境初始化。这一步会自动注册内部的WSL发行版耗时可能几分钟右下角图标变绿就算成功了。用docker version验证一下能看到client和server版本都正常说明引擎真的跑起来了。3.2 已经装完的补救目录联接大法如果你已经装好Docker Desktop又不想卸载重来可以用目录联接的方式把现有安装整体搬到D盘。目录联接是NTFS文件系统的一种重解析点程序读写原路径时系统自动把请求转发到新路径程序完全无感知。相当于给C盘那个真实目录立了一个替身替身背后是D盘。操作分几步。先把Docker完全退出托盘图标右键选择Quit然后确认没有docker相关进程残留tasklist | findstr docker如果还有进程先在任务管理器里结束它们或者注销当前Windows登录再进一次确保文件没有被占用。接着打开管理员PowerShell把程序目录复制到D盘robocopy C:\Program Files\Docker\Docker D:\Docker /E /COPYALL复制完成后删除原目录再创建联接rmdir C:\Program Files\Docker\Docker cmd /c mklink /J C:\Program Files\Docker\Docker D:\Docker同理处理数据目录。%LOCALAPPDATA%\Docker是Docker的配置和数据缓存所在地默认在C:\Users\用户名\AppData\Local\Docker里面还包含WSL相关文件。数据目录往往比程序目录更占空间一定一起搬robocopy %LOCALAPPDATA%\Docker D:\DockerAppData /E /COPYALL rmdir %LOCALAPPDATA%\Docker cmd /c mklink /J %LOCALAPPDATA%\Docker D:\DockerAppData注意rmdir在PowerShell里对非空目录也能用但是删一个包含大量小文件的目录可能比较慢。我实际经验是robocopy复制完先别急着删等验证Docker能从D盘正常启动再回来清掉原目录。用/MOVE参数虽然一条命令搞定复制加删除但传输中断时源目录已经动了恢复起来麻烦。这里有一个细节mklink是cmd的内置命令PowerShell里直接调用会报错所以我在前面加了cmd /c。也可以改用PowerShell原生的New-Item -ItemType Junction效果一样。3.3 两种方式的选择建议场景推荐方案说明全新安装命令行参数一步到位数据目录再配合WSL迁移已经装好、程序和数据都在C盘目录联接数据迁移不用重装保留现有镜像Docker升级后路径被重置彻底卸载后重装用参数法重新指定目录避免旧残留我的体会是能重来就用参数法省心已经积累了大量镜像、容器不方便重新拉的目录联接更合适。目录联接建好之后不要删除也不要让第三方清理工具扫描它。有些系统瘦身类软件会把这个junction当成无效快捷方式清理掉一旦删了Docker开机找不到文件就彻底废了。4. 真正吃空间的data目录迁移必做4.1 先搞清楚数据藏在哪个文件里程序目录搬完只是第一步。镜像和容器数据本质上都在WSL发行版的VHDX文件里这个文件不搬C盘照样往满里走。先看当前WSL里有哪些发行版wsl -l -v老版本Docker Desktop会显示两个发行版docker-desktop和docker-desktop-data。新版本大概4.30之后改成了单发行版结构通常只看到docker-desktop一个。VHDX文件的位置一般在C:\Users\用户名\AppData\Local\Docker\wsl下常见文件名有data\ext4.vhdx、disk\docker_data.vhdx。你可以直接打开这个目录按文件大小排序最大的那个就是数据大头。动手迁移前先了解一下VHDX的膨胀特性。WSL2的虚拟磁盘不会因为删除镜像而自动缩小它只会持续增大。哪怕你docker system prune清出一大堆可回收空间宿主机上看到的文件体积一点不会变。这也是为什么很多人的C盘空间莫名其妙消失。迁移顺便也是给以后的瘦身打基础。4.2 标准迁移方案导出、注销、再导入整个流程分五步核心思路是先导出成tar包注销原发行版释放C盘空间再把tar包导入到D盘。第一步完全退出Docker Desktop然后关闭所有WSL虚拟机wsl --shutdown执行完可以用wsl -l -v确认状态所有发行版应该显示Stopped。这步非常关键发行版还在运行的时候导出备份文件可能不一致后面导入出问题。第二步导出目标发行版。以老版本常见的docker-desktop-data为例wsl --export docker-desktop-data D:\backup\docker-desktop-data.tar导出的tar文件可能很大几个G到几十个G都有可能尽量放在空间充足的磁盘。如果只想迁移数据、不关心历史打包也可以跳过这步但我不建议。导出是你唯一的后悔药一旦注销失败至少还有备份。第三步注销原发行版wsl --unregister docker-desktop-data这一操作会删除该发行版原有的VHDX文件所以必须在确认导出成功之后做。老版本Docker Desktop里docker-desktop-data承载了绝大多数数据注销后C盘空间会立刻释放一大块。第四步导入到D盘新位置wsl --import docker-desktop-data D:\docker\wsl\data D:\backup\docker-desktop-data.tar --version 2命令里第一个路径是VHDX的新家目录D盘的这个目录可以事先建好也可以让WSL自己创建。第二个路径是刚才导出的tar包。执行完旧的发行版数据就落在D盘了。如果wsl -l -v只看到一个docker-desktop发行版就对这个发行版执行同样的导出、注销、导入流程命令里的发行版名称换成docker-desktop即可。第五步重新启动Docker Desktop然后验证docker version docker images之前拉过的镜像还在说明迁移成功。如果启动后Docker又自动生成了C盘新目录通常是卸载不彻底导致残留配置指向了原路径建议先彻底卸载再重装。4.3 图形界面偷懒方案如果Docker Desktop已经能正常启动又不想敲命令行新版本自带了图形化的数据位置修改功能。打开Settings进入Resources再进Advanced能看到Disk image location选项。把它改成D盘下的目录点击Apply RestartDocker会自己把数据搬过去。这个方案的好处是直观、适合新手但我实际体验下来有两个问题一是大数据量迁移时耗时很长中途最好不要关电源、不要强制重启二是迁移失败后没有清晰的恢复指引不如导出导入那么可控。总数据量在10G以内、又不缺时间的可以用这个追求稳妥的还是优先走命令行方案。4.4 顺手优化镜像加速与初始配置镜像和容器数据迁到D盘之后还要考虑拉镜像慢的问题。Windows版的Docker Desktop虽然是图形界面但底层还是守护进程配置文件在Settings Docker Engine里。可以在这个JSON配置里加registry-mirrors配置你常用的镜像加速地址。改完记得Apply Restart让配置生效。有一点特别提醒修改daemon.json之前先把原有内容复制备份到一个文本文件里。配置写错一个标点Docker Desktop可能直接起不来。真起不来了把备份内容还原回去再重启一次就能恢复。这是我自己踩过的坑谨慎一点不亏。5. 安装与迁移过程中的常见故障排查5.1 虚拟化支持检测不到最常见的报错就是那一句Docker Desktop failed to start because virtualisation support wasnt detected。按顺序排查先回任务管理器看CPU虚拟化是否为已启用没有就去BIOS开再检查Windows功能里虚拟机平台是否勾选最后看看机器上是不是同时开着VMware、VirtualBox这类虚拟化软件它们会抢占VT-x导致Docker启动失败。命令行可以辅助判断systeminfo | findstr /i Hyper-V如果输出里包含已检测到虚拟机监控程序说明Hypervisor层已经就绪。要是这个值为否那问题多半出在Windows功能或者BIOS层面和Docker本身无关。5.2 WSL2启动卡死或者直接闪退有时候Docker Desktop安装正常但第一次启动时WSL环境初始化失败日志里提示内核相关错误。新版系统直接执行wsl --update把WSL内核更新到最新版。如果更新失败先重启电脑再试一次。还有一招重启Windows的WSL服务net stop LxssManager net start LxssManager这个操作需要管理员权限。我自己遇到过一次初始化卡在WSL distro registration的情况重启LxssManager之后重新启动Docker问题就解决了。5.3 非管理员终端和shared clients报错有段时间我习惯用普通PowerShell敲docker命令偶尔会遇到类似error starting the windows daemon from a non-elevated terminal; shared clients的提示。这个报错信息比较绕多半是终端权限不够或者Docker的客户端上下文被改过。处理思路三步走。第一所有docker命令都在管理员PowerShell里执行第二检查上下文配置docker context ls docker context use default第三去Docker Desktop的Settings里看一下General相关的共享客户端选项有问题就取消勾选再重新启动。如果还不行注销当前Windows用户再重新登录一次让用户组权限彻底刷新。5.4 安装完docker命令找不到刚装完Docker、打开终端执行docker提示无法识别绝大多数原因是当前终端窗口是在安装前打开的环境变量没刷新。重新打开一个终端基本就好了。如果重新打开还是不行手动检查PATH里有没有C:\Program Files\Docker\Docker\resources\bin。用自定义目录安装的话比如装到了D盘对应路径就是D:\Docker\resources\bin。没有的话到系统环境变量里手动加上这一项。加上之后新开的终端就能正常识别docker命令了。5.5 端口占用导致MySQL、Redis起不来很多人在Windows Docker里装MySQL跑起来直接报3306端口被占用。Windows上经常有本地服务或者乱七八糟的程序抢这个口。先查谁占了端口netstat -ano | findstr :3306拿到PID之后到任务管理器里确认是什么程序不是必要的话就结束它taskkill /PID 这里填PID /F不想动占用端口的程序更省事的办法是换宿主机映射端口。比如把MySQL服务映射到3307端口docker run -d --name mysql8 -p 3307:3306 -e MYSQL_ROOT_PASSWORD123456 mysql:8.0这样访问localhost:3307就能连到容器内的3306。挂载数据目录也建议直接挂到D盘不然容器数据还是会落在C盘的虚拟磁盘里前面刚迁出去的空间又会被吃回来。5.6 VHDX文件膨胀怎么压缩前面提到VHDX只增不减。如果Docker用了一段时间D盘上这个虚拟磁盘文件已经膨胀得离谱可以用diskpart手动瘦身。先完全退出Docker并执行wsl --shutdown确保虚拟磁盘没有被挂载然后进diskpartdiskpart select vdisk fileD:\docker\wsl\data\ext4.vhdx attach vdisk readonly compact vdisk detach vdisk exitcompact执行时间取决于文件大小几十G可能要跑一阵子。压缩完成后D盘会多出一块可用空间。这个操作偶尔做一次就行不建议频繁执行毕竟它需要锁住虚拟磁盘Docker在那段时间不能使用。这次折腾下来我个人最大的体会是Windows上装Docker安装目录从来不是一个参数能解决的程序路径、WSL数据路径、VHDX膨胀三者得一起考虑。全新的机器直接用命令行参数指定程序目录然后再把WSL发行版导入到D盘是最干净的组合拳。已经装好的也别急着卸目录联接加导出导入同样能救回来。最后再多说一句不管用哪种方案操作之前把手头重要的镜像做一次备份花不了几分钟却能避免很多极端情况下的血泪教训。
返回列表