使用 WSL 与 Docker Desktop 的 VHDX 进行迁移与恢复

问题来源

整理东西回家的时候比较匆忙,由于宿舍电脑上有需要用的数据,直接把宿舍电脑上的 SSD 拔了,回到家里才反应过来有很多资料都在 WSL 和 Docker 里,必须在家里的电脑恢复 WSL 和 Docker

WSL 恢复

复制虚拟磁盘

C:\Users\[user]\AppData\Local\Packages\[distro]\LocalState\ext4.vhdx 为 WSL2 磁盘所在位置,以 Microsoft 虚拟磁盘的形式存在。将其复制到我们的新机器上,将其放置在一个空的文件夹内

编辑注册表

新建一个文本文件,输入以下内容:

1
2
3
4
5
6
7
8
9
Windows Registry Editor Version 5.00

[HKEY_USERS\[SID]\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\{[UUID]}]
"State"=dword:00000001
"DistributionName"="[DISTRO_NAME]"
"Version"=dword:00000002
"BasePath"="\\\\?\\[VHDX_PATH]"
"Flags"=dword:0000000f
"DefaultUid"=dword:000003e8

其中中括号括起来的部分分别为:

  • SID:修改为当前 Windows 用户的 SID,可以通过在 Power Shell 中执行 whoami /user 命令获取
  • UUID:子系统的唯一 ID,可以在这个网站中生成 UUID:在线随机UUID生成器 - UU在线工具 (uutool.cn)
  • DISTRO_NAME:子系统的分发名称。可以通过 wsl -l 指令查看当前 Windows 中的所有子系统分发。该名称自取,建议不要包含空格
  • VHDX_PATH:虚拟磁盘(VHDX)所在的文件夹路径,如 VHDX 绝对路径为 D:\\WSL\\ext4.vhdx 此处就应该填 D:\\WSL

修改完成后,将后缀修改为 .reg,然后双击执行注册表导入即可。

导入完成后,在 wsl -l 指令的结果中可以看到新的分发信息,通过使用 wsl -d <分发名称> 可以运行指定的子系统,也可以通过 wsl --set-default <分发名称> 指令来设置默认的子系统。

Docker Desktop 恢复

与 WSL 的恢复原理一致,Docker Desktop 的数据对应 docker-desktop-data 子系统,其虚拟磁盘默认存于

1
C:\Users\[user]\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows\LocalState\

中。

关闭 Docker 后,我们先删除本机中的 Docker 数据

1
wsl --unregister docker-desktop-data

然后如上文所说将虚拟磁盘复制到本机,然后编辑一个 .reg 文件,注意其中的分发名称必须填写 docker-desktop-data,UUID 必须重新生成。

1
2
3
4
5
6
7
8
9
Windows Registry Editor Version 5.00

[HKEY_USERS\[SID]\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\{[UUID]}]
"State"=dword:00000001
"DistributionName"="docker-desktop-data"
"Version"=dword:00000002
"BasePath"="\\\\?\\[VHDX_PATH]"
"Flags"=dword:0000000f
"DefaultUid"=dword:000003e8

编写完成后再双击执行导入注册表,随后再开启 Docker 即可。

参考资料

WSL2 Register Command · Issue #4762 · microsoft/WSL · GitHub