背景

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-desktop)

Docker 引擎运行环境

~100MB

通常不需要

数据磁盘

 (docker_data.vhdx)

镜像、容器、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执行迁移镜像/容器数据时清除

为什么导出的是 tarwsl --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 盘 log/run/ 等

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 即可。

创作不易,禁止抄袭,转载请附上原文链接及标题

更多推荐