Docker Desktop WSL 2 数据迁移:从 C 盘搬家到其他盘
背景
Docker Desktop(版本 29.6.2) 在 Windows 上使用 WSL 2 后端时,数据默认存储在:
C:\Users\<用户名>\AppData\Local\Docker\wsl\disk\docker_data.vhdx这是一个虚拟磁盘文件,随着使用会膨胀到几十 GB。C 盘吃紧时,需要把它迁移到其他盘。
以下路径均为示例,实际操作换成你自己的目标目录即可。
核心事实:这是两件独立的事
Docker Desktop 的数据迁移涉及两个独立的机制,它们之间没有依赖关系,按需选择即可:
机制 | 管理什么 | 大小 | 是否需要迁移 |
|---|---|---|---|
| WSL distro ( | Docker 引擎运行环境 | ~100MB | 通常不需要 |
| 数据磁盘 ( | 镜像、容器、volume 数据 | 几十 GB | 这是重点 |
第一件事:迁移 WSL distro(可选,通常没必要)
wsl --shutdown wsl --export docker-desktop <target-dir>\data.tar wsl --unregister docker-desktop wsl --import docker-desktop <target-dir>\ <target-dir>\data.tar --version 2这是做什么:把 Docker 引擎的 WSL 分发(docker-desktop)迁移到目标盘。
要不要做:通常没必要。100MB 对 C 盘压力微乎其微,不值得折腾。除非你有洁癖或者 C 盘真的寸土寸金。而且新版本如29.6.2执行迁移镜像/容器数据时清除
为什么导出的是 tar:wsl --export的默认输出格式就是 tar,这是 WSL 设计的通用备份/交换格式。WSL 较新版本支持--vhd参数直接导出 vhdx,但默认行为仍是 tar。
迁移完成后:可以删掉data.tar,WSL 会在导入目录生成内部的存储文件。
第二件事:迁移镜像/容器数据(这才是重点)
实际行为
在 Docker Desktop GUI 中:
Settings → Resources → Advanced → Disk image location,点击Browse选择<target-dir>(例如E:\Program\Docker),点击Apply & Restart。
Docker 会自动在指定的目录下创建DockerDesktopWSL\disk\结构,并迁移现有数据:
指定的路径: E:\Program\Docker 实际创建的结构: E:\Program\Docker\ └── DockerDesktopWSL\ ├── disk\ │ └── docker_data.vhdx ← 镜像/容器数据(这才是大头)注意:
1.Docker 不会直接在指定的目录下放文件,而是强制套层DockerDesktopWSL\disk\。
2.不同 Docker Desktop 版本行为可能不同。建议数据迁移前备份,如果迁移后数据不完整,可以手动关闭 Docker Desktop,将旧的docker_data.vhdx复制到新位置覆盖,再启动。
文件对照
文件/目录 | 来源 | 说明 | 迁移后能否删 |
|---|---|---|---|
data.tar | 第一件事的导出备份 | WSL 通用交换格式 | 可以删 |
docker_data.vhdx | 第二件事的数据磁盘 | 镜像/容器/卷数据(大头) | 保留 |
C 盘 | Docker Desktop 运行必需 | 含 lock 文件 | 不建议删 |
常见误区
❌ 误区 1:做了第一件事就等于迁移了数据
wsl --export/import docker-desktop只迁移了引擎 distro(100MB),不含镜像数据。镜像数据在docker_data.vhdx里,必须通过第二件事(GUI 改 Disk image location)才能搬走。
❌ 误区 2:两件事必须配合做
它们是独立机制。只做第二件事(GUI 改路径)就能解决 C 盘空间问题,同时解决引擎那 100MB。在新版本第一件事是可以不做,但旧版本可能仍需做。
❌ 误区 3:docker-compose 能控制镜像存储位置
docker-compose 只决定用什么镜像、端口映射、volume(数据卷) 挂载。Docker 的镜像层、容器层存储在哪儿,由 Docker Daemon 的 Disk image location 决定,compose 管不了。
❌ 误区 4:用目录联接(junction/symlink)替代官方迁移
虽然mklink /J在文件系统层面可以把目录指向另一个位置,但 Docker Desktop 的数据路径由 WSL2 和 Docker 内部管理,不保证能正确解析 junction。社区有报告 symlink 在 WSL/Windows 互操作中的兼容性问题,用 junction 替代官方迁移方式存在不确定性,不建议尝试。
附录:Volume 挂载走另一条路
虽然镜像存储位置由Disk image location控制,但应用数据(如 MySQL 表文件)可以用 bind mount 放到指定目录:
services:mysql:image: mysql:8volumes:- <your-data-dir>:/var/lib/mysql这样镜像本身在 vhdx 里,数据库文件在你指定的目录,各管各的。
注意:这里只推荐用Bind Mount(直接映射宿主机目录)。有一种"Named Volume +driver_opts强制指定路径"的写法,本质上是给 Bind Mount 套了一层 Named Volume 的壳,增加了复杂度却没有带来实质收益,不建议使用。如果确实需要 Docker 管理 volume 生命周期,就用纯 Named Volume(不指定路径,让 Docker 自行管理);如果需要控制数据存放路径,直接用 Bind Mount 即可。
创作不易,禁止抄袭,转载请附上原文链接及标题
