项目说明
适用系统所有使用 systemd 的 Linux 发行版(Ubuntu、Debian、CentOS、RHEL、Fedora、openSUSE 等)
验证环境Ubuntu 22.04 / 24.04 LTS
迁移场景将 Docker 数据目录从旧位置迁移到新位置
涉及服务docker.servicedocker.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 确认当前数据目录

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 配置

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

sudo systemctl stop docker
sudo systemctl stop docker.socket

非 systemd 系统:执行 sudo service docker stop 即可,无需处理 socket。

3.2 验证服务状态

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 彻底停止。


四、创建新目录

# 场景A(最常见):新目录在旧目录外部
sudo mkdir -p /data/docker_new

# 场景B(子目录迁移):新目录在旧目录内部
sudo mkdir -p /data/docker/docker

五、迁移数据

5.1 使用 rsync(推荐,支持断点续传)

# 场景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(快速,无额外空间占用)

# 场景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

sudo vi /etc/docker/daemon.json

修改 data-root 为新目录路径:

{
  "data-root": "/data/docker_new"
}

如果还有其他配置(如镜像源、日志限制),保留不变。


七、启动 Docker 并验证

7.1 启动服务

sudo systemctl start docker

非 systemd 系统:执行 sudo service docker start

7.2 验证数据目录

docker info | grep "Docker Root Dir"

应输出新路径。

7.3 验证容器和镜像

docker ps -a
docker images

确认原有容器和镜像均正常显示。


八、删除旧数据

⚠️ 请务必确认新目录数据完整、Docker 正常运行后,再执行删除操作。

8.1 场景A(最常见):新目录在旧目录外部(如 /data/docker_new

由于新目录与旧目录相互独立,直接删除旧目录即可:

# 先确认要删除的目录路径
ls -la /var/lib/docker

# 确认无误后删除
sudo rm -rf /var/lib/docker

说明:由于 Docker 默认目录权限为 root:root,删除时需使用 sudo

8.2 场景B(子目录迁移):新目录在旧目录内部(如 /data/docker/docker

由于新目录是旧目录的子目录,不能直接删除旧目录,需使用 find 排除新目录:

# 进入旧目录
cd /data/docker

# 查看即将删除的内容(确认要删除的文件/目录)
sudo find . -maxdepth 1 ! -name "." ! -name "docker" -printf "%p\n"

# 确认无误后,执行删除
sudo find . -maxdepth 1 ! -name "." ! -name "docker" -exec rm -rf {} \;

分步说明

  1. -maxdepth 1:只处理当前目录下的直接内容
  2. ! -name ".":排除当前目录自身
  3. ! -name "docker":排除新目录 docker
  4. -printf "%p\n":打印将要删除的内容(用于确认)
  5. -exec rm -rf {} \;:删除匹配的内容

8.3 删除后验证

# 场景A
ls -la /var/lib/docker   # 目录应不存在或为空

# 场景B
ls -la /data/docker      # 应只剩 docker 子目录
ls -la /data/docker/docker   # 应包含完整数据

九、完整迁移流程速查

场景A(最常见):/var/lib/docker/data/docker_new

# 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

# 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 命令
停止 Dockersudo systemctl stop dockersudo service docker stop
停止 socketsudo systemctl stop docker.socket跳过(无此概念)
启动 Dockersudo systemctl start dockersudo service docker start
查看状态sudo systemctl status dockersudo service docker status

其他命令(如 rsyncmvfindrm)在所有 Linux 发行版中通用,不受 init 系统影响。


附录 B:权限与路径说明

路径默认属主说明
/var/lib/dockerroot:rootDocker 默认数据目录
/data/docker_newroot:root新数据目录(迁移后)
/etc/docker/daemon.jsonroot:rootDocker 配置文件

新目录创建后,rsync 会自动同步原目录的权限属主,无需手动调整。


文档版本:2.1
适用系统:所有使用 systemd 的 Linux 发行版(Ubuntu、Debian、CentOS、RHEL、Fedora、openSUSE 等)
验证环境:Ubuntu 22.04 / 24.04 LTS
核心原则:停止 docker.socket、确认删除内容、区分新旧目录关系
发布日期:2026-07-26

更多推荐