最稳妥方式是直接修改 data-root:先用 docker info | grep "Docker Root Dir" 查当前路径并用 df -h 确认目标盘空间充足,再停 docker 和 docker.socket,rsync -aP /var/lib/docker/ /mnt/data/docker-data/ 复制,最后在 /etc/docker/daemon.json 中设 "data-root": "/mnt/data/docker-data",systemctl daemon-reload && systemctl start docker 并验证。

直接改 data-root 是最稳妥的方式,别用软链接或挂载覆盖目录,否则容易在升级、重启或 SELinux 环境下出问题。
确认当前 Docker Root Dir 和磁盘空间
先看 Docker 正在用哪条路,再确认目标盘有没有足够空间:
-
docker info | grep "Docker Root Dir"—— 一般输出类似Docker Root Dir: /var/lib/docker -
df -h /var/lib/docker和df -h /mnt/data(假设你要迁到/mnt/data)—— 确保目标路径所在分区空闲 ≥ 当前/var/lib/docker占用的 1.2 倍(留 buffer) -
sudo du -sh /var/lib/docker/*—— 快速定位大头(比如overlay2或volumes占了 90%)
停服务 + 创建目标目录 + 权限必须对
Docker 进程一写入,数据就可能不一致。权限错一个字,启动直接报 permission denied。
- 必须同时停掉
docker和docker.socket:sudo systemctl stop docker docker.socket
再用sudo systemctl status docker确认是inactive (dead) - 目标目录创建后,所有权和权限要严格匹配默认行为:
sudo mkdir -p /mnt/data/docker-datasudo chown -R root:root /mnt/data/docker-datasudo chmod -R 701 /mnt/data/docker-data(不是755,也不是777)
用 rsync 复制,末尾斜杠不能少
rsync 比 cp -a 更安全:支持断点、显示进度、且 -aP 能完整保留所有元数据(包括 overlay2 需要的扩展属性)。
- 命令必须带源路径末尾
/,否则会把整个docker目录复制进去:sudo rsync -aP /var/lib/docker/ /mnt/data/docker-data/ - 如果中途断了,重跑同一命令即可续传;别用
cp,它不保证 xattrs(特别是overlay2的trusted.overlay.*属性) - 复制完检查关键子目录是否存在:
ls -l /mnt/data/docker-data/overlay2 /mnt/data/docker-data/volumes /mnt/data/docker-data/containers
改 daemon.json 后必须 reload + restart
只改配置不 reload,Docker 守护进程根本不会读新配置;只 reload 不 restart,旧进程还在用老路径。
- 编辑
/etc/docker/daemon.json,确保只有合法 JSON:{"data-root": "/mnt/data/docker-data"}(注意:不要有多余逗号、注释或 UTF-8 BOM) - 执行两步:
sudo systemctl daemon-reloadsudo systemctl start docker - 验证:
docker info | grep "Docker Root Dir"应返回新路径sudo ls -l /mnt/data/docker-data/应看到刚复制的结构docker run --rm hello-world必须能成功拉镜像并运行
最容易被忽略的是 docker.socket 没停干净,或者 daemon.json 文件里有不可见字符 —— 这会导致 systemctl start docker 静默失败,journalctl -u docker 里才会暴露 failed to load json config。迁移不是“复制+改配置”两步,而是“停净、复准、配洁、启验”四步闭环。











