| 项目 | 说明 |
|---|---|
| 适用系统 | 所有使用 systemd 的 Linux 发行版(Ubuntu、Debian、CentOS、RHEL、Fedora、openSUSE 等) |
| 验证环境 | Ubuntu 22.04 / 24.04 LTS |
| 迁移场景 | 将 Docker 数据目录从旧位置迁移到新位置 |
| 涉及服务 | docker.service、docker.socket |
| 注意事项 | 迁移前需停止 Docker 及 socket 激活单元,避免数据损坏 |
非 systemd 系统说明 :对于使用 SysV init 的旧版系统(如 CentOS 6),请将
systemctl stop docker替换为service docker stop,并跳过docker.socket相关步骤(socket 激活机制仅在 systemd 中使用)。
一、背景说明
Docker 默认将数据存储在 /var/lib/docker。当系统盘空间不足时,需要将数据迁移到容量更大的分区或目录。本文档提供完整的迁移步骤,涵盖两种常见场景:
| 场景 | 迁移路径 | 说明 |
|---|---|---|
| 场景A(最常见) | /var/lib/docker → /data/docker_new |
从系统盘默认位置迁移到数据盘或大容量分区 |
| 场景B(子目录迁移) | /data/docker → /data/docker/docker |
在已有自定义目录下调整子目录层级 |
二、迁移前准备
2.1 确认当前数据目录
bash
docker info | grep "Docker Root Dir"
示例输出:
Docker Root Dir: /var/lib/docker # 场景A
# 或
Docker Root Dir: /data/docker # 场景B
2.2 确认新目录位置
根据你的需求,决定新目录位置:
- 场景A(最常见) :
/var/lib/docker→/data/docker_new(新目录在旧目录外部) - 场景B(子目录迁移) :
/data/docker→/data/docker/docker(新目录在旧目录内部)
2.3 备份 Docker 配置
bash
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
三、停止 Docker 服务
3.1 停止 docker.service 和 docker.socket
Docker 使用了 socket 激活机制(docker.socket),即使停止 docker.service,当有客户端通过 /var/run/docker.sock 发起请求时,systemd 会自动重启服务。
因此,必须同时停止 docker.socket:
bash
sudo systemctl stop docker
sudo systemctl stop docker.socket
非 systemd 系统 :执行
sudo service docker stop即可,无需处理 socket。
3.2 验证服务状态
bash
sudo systemctl status docker docker.socket
两者均应显示 inactive (dead)。
3.3 关于警告信息的说明
如果只执行 sudo systemctl stop docker,可能会看到以下警告:
Stopping 'docker.service', but its triggering units are still active:
docker.socket
这不是错误 ,而是 systemd 的提示,说明 docker.socket 仍处于激活状态,可能会在连接请求时唤醒 docker.service。因此,必须执行 sudo systemctl stop docker.socket 彻底停止。
四、创建新目录
bash
# 场景A(最常见):新目录在旧目录外部
sudo mkdir -p /data/docker_new
# 场景B(子目录迁移):新目录在旧目录内部
sudo mkdir -p /data/docker/docker
五、迁移数据
5.1 使用 rsync(推荐,支持断点续传)
bash
# 场景A:/var/lib/docker → /data/docker_new
sudo rsync -avxP /var/lib/docker/ /data/docker_new/
# 场景B:/data/docker → /data/docker/docker
sudo rsync -avxP /data/docker/ /data/docker/docker/
参数说明:
-a:归档模式,保留权限、时间戳等-v:详细输出-x:不跨文件系统-P:显示进度并支持断点续传
5.2 使用 mv(快速,无额外空间占用)
bash
# 场景A:直接移动整个目录
sudo mv /var/lib/docker /data/docker_new
# 场景B:先移动非隐藏文件,再移动隐藏文件
sudo mv /data/docker/* /data/docker/docker/ 2>/dev/null
sudo mv /data/docker/.[!.]* /data/docker/docker/ 2>/dev/null
注意:
2>/dev/null用于忽略"没有匹配文件"的提示- 场景B中隐藏文件(以
.开头)需要单独移动
六、修改 Docker 配置
编辑 /etc/docker/daemon.json:
bash
sudo vi /etc/docker/daemon.json
修改 data-root 为新目录路径:
json
{
"data-root": "/data/docker_new"
}
如果还有其他配置(如镜像源、日志限制),保留不变。
七、启动 Docker 并验证
7.1 启动服务
bash
sudo systemctl start docker
非 systemd 系统 :执行
sudo service docker start。
7.2 验证数据目录
bash
docker info | grep "Docker Root Dir"
应输出新路径。
7.3 验证容器和镜像
bash
docker ps -a
docker images
确认原有容器和镜像均正常显示。
八、删除旧数据
⚠️ 请务必确认新目录数据完整、Docker 正常运行后,再执行删除操作。
8.1 场景A(最常见):新目录在旧目录外部(如 /data/docker_new)
由于新目录与旧目录相互独立,直接删除旧目录即可:
bash
# 先确认要删除的目录路径
ls -la /var/lib/docker
# 确认无误后删除
sudo rm -rf /var/lib/docker
说明 :由于 Docker 默认目录权限为
root:root,删除时需使用sudo。
8.2 场景B(子目录迁移):新目录在旧目录内部(如 /data/docker/docker)
由于新目录是旧目录的子目录,不能直接删除旧目录 ,需使用 find 排除新目录:
bash
# 进入旧目录
cd /data/docker
# 查看即将删除的内容(确认要删除的文件/目录)
sudo find . -maxdepth 1 ! -name "." ! -name "docker" -printf "%p\n"
# 确认无误后,执行删除
sudo find . -maxdepth 1 ! -name "." ! -name "docker" -exec rm -rf {} \;
分步说明:
-maxdepth 1:只处理当前目录下的直接内容! -name ".":排除当前目录自身! -name "docker":排除新目录docker-printf "%p\n":打印将要删除的内容(用于确认)-exec rm -rf {} \;:删除匹配的内容
8.3 删除后验证
bash
# 场景A
ls -la /var/lib/docker # 目录应不存在或为空
# 场景B
ls -la /data/docker # 应只剩 docker 子目录
ls -la /data/docker/docker # 应包含完整数据
九、完整迁移流程速查
场景A(最常见):/var/lib/docker → /data/docker_new
bash
# 1. 停止服务
sudo systemctl stop docker
sudo systemctl stop docker.socket
# 2. 创建新目录
sudo mkdir -p /data/docker_new
# 3. 迁移数据
sudo rsync -avxP /var/lib/docker/ /data/docker_new/
# 4. 修改配置
sudo vi /etc/docker/daemon.json # data-root: /data/docker_new
# 5. 启动验证
sudo systemctl start docker
docker info | grep "Docker Root Dir"
# 6. 确认无误后删除旧目录
ls -la /var/lib/docker # 确认
sudo rm -rf /var/lib/docker
场景B(子目录迁移):/data/docker → /data/docker/docker
bash
# 1. 停止服务
sudo systemctl stop docker
sudo systemctl stop docker.socket
# 2. 创建新目录
sudo mkdir -p /data/docker/docker
# 3. 迁移数据
sudo rsync -avxP /data/docker/ /data/docker/docker/
# 4. 修改配置
sudo vi /etc/docker/daemon.json # data-root: /data/docker/docker
# 5. 启动验证
sudo systemctl start docker
docker info | grep "Docker Root Dir"
# 6. 确认无误后删除旧数据(排除新目录)
cd /data/docker
sudo find . -maxdepth 1 ! -name "." ! -name "docker" -printf "%p\n" # 确认
sudo find . -maxdepth 1 ! -name "." ! -name "docker" -exec rm -rf {} \;
十、常见问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
docker info 显示旧路径 |
配置未生效 | 检查 daemon.json 格式,重启 Docker |
| 迁移后容器丢失 | 数据未完全同步或路径错误 | 检查 rsync 命令是否完整,确认新旧路径正确 |
rm -rf 误删新目录 |
通配符展开了新目录 | 场景B使用 find 排除方法 |
| Docker 启动失败 | daemon.json 语法错误 |
检查 JSON 格式(逗号、引号) |
| 迁移后磁盘空间未释放 | 旧数据仍在 | 确认删除操作已执行 |
no space left on device |
迁移时空间不足 | 使用 mv 代替 rsync,或先清理旧镜像 |
附录 A:非 systemd 系统操作差异
对于不使用 systemd 的旧版 Linux 系统(如 CentOS 6、Debian 7 等),请参考以下替换命令:
| 操作 | systemd 命令 | SysV init 命令 |
|---|---|---|
| 停止 Docker | sudo systemctl stop docker |
sudo service docker stop |
| 停止 socket | sudo systemctl stop docker.socket |
跳过(无此概念) |
| 启动 Docker | sudo systemctl start docker |
sudo service docker start |
| 查看状态 | sudo systemctl status docker |
sudo service docker status |
其他命令 (如 rsync、mv、find、rm)在所有 Linux 发行版中通用,不受 init 系统影响。
附录 B:权限与路径说明
| 路径 | 默认属主 | 说明 |
|---|---|---|
/var/lib/docker |
root:root |
Docker 默认数据目录 |
/data/docker_new |
root:root |
新数据目录(迁移后) |
/etc/docker/daemon.json |
root:root |
Docker 配置文件 |
新目录创建后,
rsync会自动同步原目录的权限属主,无需手动调整。
文档版本 :2.1
适用系统 :所有使用 systemd 的 Linux 发行版(Ubuntu、Debian、CentOS、RHEL、Fedora、openSUSE 等)
验证环境 :Ubuntu 22.04 / 24.04 LTS
核心原则 :停止
docker.socket、确认删除内容、区分新旧目录关系发布日期:2026-07-26