前两天一个同事跑过来问我:升级 Docker Desktop 到 4.3 以上版本之后,wsl --list 里看不到 docker-desktop-data 了,可之前花了半天时间迁移到 D 盘的那堆镜像数据还躺在旧发行版里,怎么才能把数据搬回新的 Docker Desktop?
这个问题其实在升级 4.3+ 的用户里非常典型。老版本里大家习惯把 docker-desktop-data 迁到 D 盘给 C 盘腾地方,结果 Docker 官方在 4.3 版本改动 WSL2 后端架构,不再依赖 docker-desktop-data 这个独立发行版存数据了。新版本的数据区变成了 docker-desktop 内部的 /var/lib/docker,但旧数据不会自动跟过来。这篇就把新旧架构的差异、升级前后的数据抢救方案、以及 4.3+ 之后怎么把整个数据区换到其他磁盘,一次性讲清楚。
1. 升级后数据"凭空消失":先弄懂新旧架构的存储差异
1.1 旧版WSL2后端:docker-desktop-data 到底在干什么
在 Docker Desktop 4.3 之前,只要你开启的是 WSL2 后端,安装完成之后系统里会注册两个 WSL 发行版:docker-desktop和docker-desktop-data。
这两个发行版分工很明确。docker-desktop负责运行 Docker 引擎相关的二进制文件、dockerd 守护进程、CLI 工具这些"程序文件"。而docker-desktop-data是真正的"数据仓库",里面挂载了 Docker 的/var/lib/docker目录。你拉下来的镜像层、创建的容器读写层、命名卷、构建缓存,全部存放在这个发行版里。
这两个发行版的虚拟磁盘文件默认落在同一个位置:
C:\Users\<用户名>\AppData\Local\Docker\wsl\disk\其中 docker-desktop 对应的虚拟磁盘文件一般叫docker-desktop.vhdx,docker-desktop-data 对应的叫docker-desktop-data.vhdx。
很多人当初迁移 docker-desktop-data,就是因为它对应的 vhdx 文件膨胀最厉害。镜像个一多,几十 GB 甚至上百 GB 都很常见。C 盘装不下,网上自然就出现了大量教程教大家用wsl --export/wsl --import把 docker-desktop-data 这个发行版整体搬到 D 盘,甚至还有人直接在磁盘层面移动 vhdx 文件再建符号链接。这些办法在当时都有效,问题在于 Docker Desktop 的架构后来变了。
1.2 新版为什么砍掉 docker-desktop-data
Docker Desktop 4.3 发布时,官方做了一个影响面很大的改动:WSL2 后端不再单独创建 docker-desktop-data 发行版,所有 Docker 数据直接归入 docker-desktop 发行版内部的/var/lib/docker路径。
这样改的主要原因是两点。
第一,老的架构下两个发行版职责重叠,用户很难搞清楚"到底哪个发行版占了我 40GB 空间",而且 Docker Desktop 在清理镜像、收缩磁盘空间时,需要同时管理两个 vhdx 文件,很容易出现数据目录残留。
第二,新版本希望把 Docker Desktop 的资源识别做得更简单,一个发行版对应一套数据,排查问题、做健康检查都省事。
升级到 4.3+ 之后,如果你在 WSL 里注册表还保留着 docker-desktop-data,它不会被自动删除,但已经变成了"孤儿发行版",Docker Desktop 根本不会再往里面写任何新数据。
1.3 "数据消失"的本质:Docker Desktop 不会自动迁移
我在帮同事排查的时候,他的第一反应是"我镜像是不是丢了"。
其实没有丢。他的 Docker Desktop 升级之后,界面确实变成了全新状态,docker images列表是空的。但这只是因为他之前的镜像全部待在 docker-desktop-data 的 /var/lib/docker 里,新版 Docker Desktop 启动时会用 docker-desktop 发行版里那个全新的、空的 /var/lib/docker。旧数据被完全跳过,看起来像是消失了。
所以核心就一句话:Docker Desktop 升级时不会替你做数据迁移,旧发行版里的数据要你自己想办法搬过去。想明白这一点,后面的操作就顺了。
2. 动手前先体检:确认你正处于哪条升级路径
2.1 第一步:查看 WSL 发行版清单
先打开 PowerShell 或者 Windows Terminal,执行:
wsl --list --verbose正常情况你会看到以下几种可能。
一,如果docker-desktop-data还在列表里,说明是从旧版升级上来的,而且 WSL 发行版没有被手动删掉。
二,如果列表里只有docker-desktop这一个 Docker 相关发行版,那大概率是全新安装的 4.3+,又或者早先已经手动卸载了 docker-desktop-data。这时候不存在旧数据可迁,不用往下看。
三,列表里还可能出现 docker-desktop-data 但状态是 Stopped,这种情况最常见,因为新版 Docker Desktop 不再启动它了。
我建议同时再看一眼 WSL 发行版的安装位置。用这条命令:
wsl --list --verbose --all注册表信息可以通过注册表编辑器查,不过用命令行更简单。打开regedit,定位到:
HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss每个子键对应一个 WSL 发行版,BasePath字段写的就是这个发行版的 vhdx 文件所在目录。这一步能帮你确认当初 docker-desktop-data 是不是已经被搬到 D 盘了。
2.2 第二步:检查新旧发行版里的 Docker 数据
光看到发行版存在还不够,你得确认里面到底有没有数据。分别执行以下命令查看两个发行版 /var/lib/docker 目录的内容:
wsl -d docker-desktop-data -u root -- ls -la /var/lib/docker wsl -d docker-desktop -u root -- ls -la /var/lib/docker注意,如果对应发行版没有启动,这个命令会先把它启动起来。如果 docker-desktop-data 里能看到image、containers、volumes这些目录,说明旧数据完好。如果 docker-desktop 里只有buildkit、containerd之类的新初始化目录,说明新版还处于"待迁移"的干净状态。
2.3 三种升级路径,三种处理策略
我接触过的用户基本落在这三种情况里,对应处理方式差异很大。
| 升级路径 | 特征 | 处理策略 |
|---|---|---|
| 旧版直接升级,没动过 docker-desktop-data | docker-desktop-data 还在默认 C 盘位置,里面有完整数据 | 直接把 /var/lib/docker 内容复制到新版 docker-desktop 数据区 |
| 旧版把 docker-desktop-data 迁移到 D 盘(或移动过 vhdx) | docker-desktop-data 的 BasePath 指向 D 盘,数据完整 | 直接对 D 盘里的 docker-desktop-data 打包导出,再导入新版,方法一致 |
| 已经全新安装 4.3+,且 docker-desktop-data 已注销 | wsl --list 中已无 docker-desktop-data | 除非有 tar 备份,否则数据已不可找回,只能重新拉镜像 |
大多数来问"无 docker-desktop-data 如何迁移"的人,都是第二种:数据还在 D 盘,只是新版本不认它了。这种情况数据一点没丢,放心往下操作。
3. 还在旧版本?升级前的抢救式备份操作
如果你现在还在 Docker Desktop 4.2 及以下版本,还没有升级,那我强烈建议你先别急着升,先花几分钟做一个完整备份。这是成本最低、成功率最高的时间点。
3.1 完整备份 docker-desktop-data
升级之前,把整个 docker-desktop-data 发行版导出为一个 tar 文件。这个 tar 文件相当于整块虚拟磁盘的逻辑备份,里面包含了所有镜像层、容器、卷数据。
操作步骤很简单:
先关闭 Docker Desktop。注意不只是退出窗口,要右键托盘图标选 Quit,确认进程彻底结束。然后执行:
wsl --shutdown mkdir D:\docker-backup wsl --export docker-desktop-data D:\docker-backup\docker-desktop-data-backup.tarwsl --export会把整个发行版导出成一个 tar 文件。导出过程中如果提示发行版正在使用,多半是 Docker Desktop 的进程没有关干净,回到第一步再做一次wsl --shutdown,等几秒再导出。
导出的 tar 文件大小约等于你现有 vhdx 里实际使用的数据量,不是整个磁盘大小。比如你拉了一堆大镜像,总共占用 30GB,导出 tar 一般也是 30GB 左右。
3.2 升级前要不要把数据"迁回C盘":我的建议是别折腾
网上有些教程说:升级前最好把 docker-desktop-data 迁回默认位置,否则新版找不到会出问题。
我的建议恰恰相反:不要折腾迁回。
原因很简单。新版 Docker Desktop 根本不再读取 docker-desktop-data 这个发行版了,它无论放在 C 盘还是 D 盘,对 4.3+ 来说都一样是"外部数据"。与其花时间把几十 GB 的 vhdx 搬回 C 盘,不如只保留一个 tar 备份,升级之后再用数据导入方式搬进新发行版。
而且,如果你手动把 docker-desktop-data 注销再重新导入回默认位置,中间一旦操作失误,丢数据的概率反而更高。
3.3 备份留底后要回退旧版,怎么恢复
有一种情况你得注意:升级新版之后,Docker Desktop 不一定满足你的需求,想退回旧版,这时备份就派上用场了。
重新安装旧版本 Docker Desktop,按它自己的安装流程执行。装好之后,如果 WSL 发行版注册表里已经丢失了 docker-desktop-data,就用备份恢复:
wsl --shutdown wsl --import docker-desktop-data C:\Users\<用户名>\AppData\Local\Docker\wsl\data D:\docker-backup\docker-desktop-data-backup.tar --version 2第二条命令的第二个参数是docker-desktop-data新的安装目录,第三个参数是刚才导出的 tar 文件路径。--version 2表示创建 WSL2 类型的发行版。
恢复完成后,再次启动旧版 Docker Desktop,数据和升级前一模一样。
4. 已经升级了?把旧数据完整导入新数据区的实操流程
这是整篇文章的核心部分。前提是你已经升级到 4.3+,且确认旧 docker-desktop-data 里还有数据。接下来按我给的步骤一步步来,别跳步。
4.1 迁移方案:用 tar 在两套 WSL 发行版之间搬运数据
既然新版本只认 docker-desktop 发行版里的 /var/lib/docker,那迁移的本质就是:把旧 docker-desktop-data 发行版里的 /var/lib/docker 完整搬运到 docker-desktop 发行版里的 /var/lib/docker。
搬运方式我首选tar,而不是直接在文件资源管理器里通过\\wsl$路径复制。
原因有两点。
第一,Docker 的 /var/lib/docker 目录下存在大量硬链接和符号链接,比如镜像层之间的复用硬链接。tar 能原样保留文件的链接关系,资源管理器复制则会按普通文件处理,搞完之后镜像存储结构就乱了。
第二,通过\\wsl$复制大目录,如果中途碰到设备忙、路径被占用,很容易半途而废。而 tar 在 WSL 内部操作,不受 Windows 文件系统锁的限制,稳定得多。
4.2 迁移命令逐条拆解
下面以 docker-desktop-data 已被迁移到 D 盘为例。如果你的它在 C 盘,步骤完全相同。
第一步,准备一个中间目录放打包文件,建议放在 Windows 侧:
wsl --shutdown mkdir D:\docker-backup第二步,进入旧发行版,将 /var/lib/docker 打包到 D 盘:
wsl -d docker-desktop-data -u root -- tar -cf /mnt/d/docker-backup/old-docker-data.tar -C / var/lib/docker参数说明:-C /把当前目录切到根目录,var/lib/docker表示打包根目录下的 var/lib/docker 整个路径。这样 tar 包内保存的路径就是var/lib/docker/...,解压时直接释放到目标发行版的根目录即可。
这一步打包期间建议不要操作 Docker 相关的命令,因为 docker-desktop-data 里没有运行 dockerd,文件本身是静态的,不会有写入,安全性没问题。
第三步,查看新版 docker-desktop 里 /var/lib/docker 是否已经有初始化数据:
wsl -d docker-desktop -u root -- ls -la /var/lib/docker如果目录是空的,或者只有一堆空的子目录,直接进行第四步。如果里面有image、containers等实际数据,说明 Docker Desktop 已经初始化过一套环境了。这时我强烈建议先把现有数据挪走,不要直接合并两个数据目录,否则新旧数据交错,容器与镜像 ID 对不上,后面很难排查:
wsl -d docker-desktop -u root -- mv /var/lib/docker /var/lib/docker.newinit直接改名,不会影响 Docker Desktop 下次启动重新创建新目录。等旧数据解压完毕,验证没问题后,再删掉这个docker.newinit目录。
第四步,解压旧数据到新发行版:
wsl -d docker-desktop -u root -- tar -xf /mnt/d/docker-backup/old-docker-data.tar -C /这一步需要等一段时间,几十 GB 的数据解压可能要几分钟。解压过程不刷屏是正常的,可以另外开一个终端用wsl -d docker-desktop -u root -- du -sh /var/lib/docker看大小是否在增长。
第五步,停掉所有手动启动的 WSL 发行版,然后启动 Docker Desktop:
wsl --shutdown接着正常打开 Docker Desktop。首次启动会稍微慢一点,因为要在新目录里重建 docker 引擎状态,但不影响旧数据识别。
4.3 迁移后验证:镜像、容器、卷一个都不能少
Docker Desktop 启动后,打开终端验证三件套:
docker images docker ps -a docker volume ls重点是docker images的输出。如果之前有 nginx、mysql、redis 等镜像,现在应该全部复现。可以再抽一个旧容器启动测试,比如:
docker start <旧容器名>能正常起来基本就说明数据完整。如果容器启动报找不到镜像,很可能是 image 存储不完整,常见原因是 tar 解压时因为磁盘空间不足中断了。
另外,如果 docker-desktop 发行版里我之前保留了/var/lib/docker.newinit目录,验证旧数据没问题后,可以清掉它:
wsl -d docker-desktop -u root -- rm -rf /var/lib/docker.newinit4.4 确认无误后再删除旧发行版
数据迁移成功且验证无误后,docker-desktop-data 这个孤儿发行版就可以清理了。清理命令:
wsl --shutdown wsl --unregister docker-desktop-data--unregister会把整个发行版包括它对应的 vhdx 文件全部删除。删除之后想找回就难了,所以我建议你先保留第 3 节里导出的 tar 备份,至少放一个礼拜,确认新环境稳定运行再删备份。
如果你之前把 docker-desktop-data 的 vhdx 手动搬到了 D 盘,注销发行版后,那个 vhdx 文件如果还在,可以手动删掉,因为它已经没有任何用了。
5. 后续存储换盘指南:新版 docker-desktop 数据区搬家
迁移完旧数据之后,很多人会发现一个问题:新版 docker-desktop 发行版的 vhdx 在 C 盘,上次是"为了给 C 盘腾地方"才迁的数据,现在又回到 C 盘了,等于白折腾。
别急,4.3+ 的新版数据区同样可以整体搬家到其他磁盘。下面给出两种方案。
5.1 新版数据都在哪个文件里
先确认现状。新版 Docker Desktop 的 docker-desktop 发行版虚拟磁盘文件,默认在:
C:\Users\<用户名>\AppData\Local\Docker\wsl\disk\docker-desktop.vhdx你可以在资源管理器里看这个文件的大小,它就是整个 docker-desktop 发行版内容的物理存储。注意,Windows 资源管理器显示的是"已分配大小",不是实际磁盘占用,vhd 是动态扩展的,真实占用看 WSL 内部 du 更准。
5.2 方案一:WSL export/import 换盘
这个方案是从 WSL 层面做一次完整的发行版迁移,逻辑上最正规,适合所有人。
wsl --shutdown wsl --export docker-desktop D:\docker-backup\docker-desktop-full.tar注意,这里导出的是整个 docker-desktop 发行版,包含了 Docker 引擎运行时和数据目录,tar 会比较大。导出完成后:
wsl --unregister docker-desktop wsl --import docker-desktop D:\Docker\wsl\docker-desktop D:\docker-backup\docker-desktop-full.tar --version 2第二条命令第一个参数是发行版名,必须是 docker-desktop;第二个参数是新的安装目录;第三个参数是 tar 路径。
导入需要一点时间。完成之后启动 Docker Desktop,它的 WSL 发行版就会从新目录加载。验证方式:在注册表里看 docker-desktop 的 BasePath 是否指向新的 D 盘路径。
这个方案的坑在于,Docker Desktop 可能会在启动时检测 docker-desktop 发行版状态,如果它认为发行版行为异常,可能自动重新初始化。稳妥起见,做完 import 后先手动启动一次该发行版:
wsl -d docker-desktop确认能进入 shell,再启动 Docker Desktop。
5.3 方案二:vhdx 文件移动 + 符号链接
如果你不想重新导入完整发行版,还有一个轻量方案:直接把 vhdx 文件移动到 D 盘,在原来的位置建立一个符号链接,让 WSL 通过链接路径找到文件。
步骤如下。
先关闭所有 WSL 发行版:
wsl --shutdown然后把 vhdx 文件移动到目标位置。假设移到D:\Docker\wsl\disk\docker-desktop.vhdx,注意目标目录要提前建好。
接着用管理员身份打开 cmd,创建符号链接:
mklink "C:\Users\<用户名>\AppData\Local\Docker\wsl\disk\docker-desktop.vhdx" "D:\Docker\wsl\disk\docker-desktop.vhdx"注意此命令有两个参数:符号链接路径在前,实际文件路径在后。创建成功后,再启动 Docker Desktop,因为原路径里有了一个指向 D 盘文件的链接,WSL 以为自己还在用 C 盘路径,实际读写都落在 D 盘,数据自然跟着走。
5.4 两种方案的对比
| 维度 | 方案一:WSL export/import | 方案二:vhdx移动+符号链接 |
|---|---|---|
| 操作难度 | 中等,三步命令 | 低,一条 move + 一条 mklink |
| 数据安全性 | 高,导出包可回退 | 中等,移动过程中中断可能损坏 vhdx |
| 迁移耗时 | 长,需要完整导出导入几十GB | 短,文件移动按磁盘速度 |
| 后续维护 | 无副作用 | Docker Desktop 更新时可能替换 vhdx 导致链接失效 |
| 适合谁 | 新手 / 追求稳妥 | 老手 / 追求快速 |
我个人更推荐方案一。虽然耗时,但导出包本身就是一份随时可以恢复的完整备份,出了问题能回到初始状态。方案二快归快,但 Docker Desktop 大版本更新时如果重新生成了 vhdx 文件,原有的符号链接可能会被替换掉,到时候又得重新人工处理。
6. 踩坑经验与最终建议
6.1 最容易踩的五个坑
第一个坑是忘了wsl --shutdown就直接导出。导出时提示发行版正在使用,或者导出完成后文件不完整。解决办法就是执行命令前先关闭 Docker Desktop,再用wsl --shutdown把 WSL 全部停掉。
第二个坑是直接用资源管理器拖\\wsl$路径下的数据。因为 WSL 的 vhd 文件在后台会写,直接复制大目录经常拖到一半卡死。而且硬链接关系会丢失,后面镜像存储出错,docker images能看到镜像名,启动容器却报找不到镜像层。
第三个坑是迁移过程中磁盘空间不够。无论是 tar 打包还是解压,都会需要一块额外的临时空间,大小约等于数据总量。有人 D 盘剩 5GB 就敢迁 30GB 的数据,结果解压到一半失败,源目录倒是没坏,但迁移做完后发现部分镜像不完整。建议预留数据量 1.5 倍以上空间。
第四个坑是忽略新版数据区是否已经初始化。Docker Desktop 运行过一次之后,/var/lib/docker 下就会生成 containerd、buildkit 等状态,这时直接 tar -xf 旧数据进去,可能覆盖掉新版运行时需要的目录结构。我在第 4.2 里已经写了,必须先 mv 改名再解压。
第五个坑是迁移完成后的权限问题。docker 的数据文件属主是 root,如果你曾经用非 root 用户在 WSL 里复制过数据,后面操作会碰上一堆 Permission Denied。我自己一般固定用-u root执行迁移命令,避免权限错乱。
6.2 到底要不要保留全部历史数据
每次遇到这种迁移,我都会问当事人一句:这些旧数据你真正还需要吗?
如果是个人开发机,里面大多数镜像是从公共仓库拉的标准镜像,容器也就是临时跑的,那完全没必要费劲迁移。直接在新环境里重新docker pull、重建容器,可能比迁移更省事,还能顺手清理掉一堆废弃镜像。
如果是企业内网环境,没法直接访问镜像仓库,必须从离线 tar 里恢复镜像,或者你有一套跑了几百天的业务容器,数据卷里有不能丢的数据库文件,那才值得做迁移。我自己迁移过同事的 GitLab 容器数据,里面仓库仓库数据量大,迁移一次花了三四个小时,但能保留全部流水线记录,值得。
6.3 一些实操后的个人建议
最后分享几个我用了很久的小习惯。
第一,WSL 发行版迁移这件事,不管你用哪种方案,操作之前一定先把wsl --list --verbose的输出和注册表里 BasePath 路径截图保存。出了事至少能知道原来发行版叫什么、放在哪。
第二,Docker Desktop 升级前不要只看版本号,先看 release notes 里有没有 WSL 后端变更。Docker 官方在这类架构调整上虽然会写说明,但不会主动帮你迁移数据,早晚要自己处理,早做打算能避免一堆麻烦。
第三,如果你长期被 Docker 数据占满 C 盘困扰,建议从一开始就把整个 docker-desktop 发行版迁到 D 盘,而不是只迁 docker-desktop-data。新版架构下只迁一个发行版,管理起来反而简单。
第四,做完迁移后,启动 Docker Desktop 之前记得用wsl --shutdown再开一次。这一步能确保 WSL 服务重新读取注册表里的发行版路径,避免因为缓存造成路径识别异常。
数据迁移这种事,看着复杂,实际上只要把新旧架构弄清楚、按顺序保守操作,成功率很高。如果万一你在迁移过程中遇到 Docker Desktop 启动失败或者镜像列表为空,先别慌着重装系统,检查一下 docker-desktop 发行版里的 /var/lib/docker 目录还在不在,tar 备份还有没有,多半只是路径没对上,重新执行一次导入流程就能救回来。