Linux 修改 Docker 镜像和容器默认目录(超详细实操版)

默认情况下,Docker 的所有数据(包括镜像、容器、卷、网络等)都会存储在 /var/lib/docker 目录下,而这个目录通常位于系统根分区。如果经常拉取大型镜像、运行多个容器,根分区很容易被耗尽,进而导致 Docker 无法正常运行,甚至影响整个系统的稳定性。

下面介绍修改容器和镜像默认目录的方法

一、前期准备

1. 查看当前 Docker 默认存储目录

首先我们可以通过以下命令,确认当前 Docker 的数据根目录(也就是镜像和容器的默认存储目录),验证修改前后的变化:

# 查看 Docker 系统信息,过滤出存储根目录
docker info | grep "Docker Root Dir"

正常输出如下(默认路径):

Docker Root Dir: /var/lib/docker

其中 /var/lib/docker 就是默认存储目录,里面包含了镜像(images)、容器(containers)、卷(volumes)、网络(network)等所有 Docker 相关数据,我们后续的操作就是修改这个路径。

2. 停止 Docker 服务

修改目录前必须停止 Docker 服务,否则会导致数据读写异常、文件损坏。执行以下命令停止服务:

# 停止 Docker 服务
sudo systemctl stop docker
# 可选:停止 Docker .socket(部分系统需要,确保完全停止)
sudo systemctl stop docker.socket
# 查看 Docker 服务状态,确认已停止
sudo systemctl status docker

输出中显示 inactive (dead) 即为停止成功。

3. 备份原有 Docker 数据(可选但强烈推荐)

如果原有目录下有重要的镜像、容器(未备份的),建议先备份数据,避免修改过程中意外丢失。备份方法有两种,按需选择:

方法 1:打包备份(适合数据量不大的情况)

# 进入默认目录的上级目录
cd /var/lib/
# 打包 docker 目录到 /home 下(可修改备份路径)
sudo tar -zcvf /home/docker_backup.tar.gz docker/

方法 2:复制备份(适合数据量大,推荐使用 rsync 保留权限)

# 使用 rsync 复制到新目录(示例备份到 /home/docker_backup)
sudo rsync -aP /var/lib/docker/ /home/docker_backup/

备份完成后,后续即使修改失败,也可以通过备份文件恢复数据。

4. 准备新的存储目录

选择一个空间充足的分区(建议剩余空间 ≥ 100G,根据自身需求调整),创建新的 Docker 存储目录。示例中我们使用 /data/docker作为新目录,大家可根据实际情况修改路径(如 /home/docker/mnt/docker 等)。

# 创建新目录(递归创建,确保上级目录存在)
sudo mkdir -p /data/docker
# 设置目录权限(关键!Docker 运行需要 root 权限,确保权限正确)
sudo chown root:root /data/docker
sudo chmod 700 /data/docker

权限说明:700 表示只有 root 用户可读写执行,避免其他用户篡改 Docker 数据,保障安全性;root:root 是 Docker 运行所需的默认用户组,必须设置正确,否则会导致 Docker 启动失败。

补充:如果你的系统启用了 SELinux(如 CentOS、RHEL 系列),还需要调整目录的 SELinux 上下文,否则会因权限限制导致 Docker 无法访问新目录,执行以下命令:

# 添加 SELinux 上下文(适配新目录)
sudo semanage fcontext -a -t container_var_lib_t "/data/docker(/.*)?"
# 应用上下文设置
sudo restorecon -R /data/docker

Ubuntu 系统默认关闭 SELinux,可跳过此步骤。

二、三种修改方法(按需选择,推荐方法一)

以下三种方法均可实现修改 Docker 镜像和容器的默认目录,其中 方法一(修改 daemon.json) 是 Docker 官方推荐的方式,适配 Docker 17.06 及以上版本(目前主流版本均支持),操作简单、稳定可靠,优先推荐;方法二(软链接)适合快速临时修改,无需修改配置文件;方法三(修改 systemd 启动参数)属于过时方法,仅适配旧版本 Docker,不推荐优先使用。

方法一:修改 Docker 配置文件(daemon.json,推荐)

Docker 的核心配置文件是 /etc/docker/daemon.json,通过添加 data-root 字段,即可指定新的存储目录。该方法无需修改系统服务配置,重启 Docker 即可生效,且后续可随时修改,灵活性高。

步骤 1:编辑 daemon.json 配置文件

首先检查该文件是否存在(部分系统默认没有此文件,需新建):

# 查看文件是否存在
ls /etc/docker/daemon.json

情况 1:文件不存在(新建文件并编辑)

sudo vim /etc/docker/daemon.json

在文件中添加以下内容(仅保留 data-root 字段即可,若有其他配置如镜像加速器,可合并添加):

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

情况 2:文件已存在(如已有镜像加速器配置,合并添加 data-root 字段)

示例原有配置(镜像加速器):

{
  "registry-mirrors": ["https://docker.mirrors.aliyun.com"]
}

修改后(添加 data-root 字段,注意 JSON 格式合法,逗号分隔,不允许末尾多逗号):

{
  "registry-mirrors": ["https://docker.mirrors.aliyun.com"],
  "data-root": "/data/docker"
}

关键提醒:JSON 格式严格区分大小写,且不能有语法错误(如逗号遗漏、引号不匹配),否则 Docker 启动失败。若不确定格式是否正确,可通过 jsonlint.com 在线验证。

步骤 2:迁移原有数据(可选)

如果原有 /var/lib/docker 目录下有镜像、容器,需要将其迁移到新目录,否则修改后原有镜像、容器会消失(仅新拉取的镜像、新建的容器会存储在新目录)。

推荐使用 rsync 命令迁移(保留文件权限和属性,比 mv 命令更安全,且可保留原数据备份):

# 迁移原有数据到新目录(注意末尾的 /,表示复制目录内所有内容,而非目录本身)
sudo rsync -aP /var/lib/docker/ /data/docker/

参数说明:-a 表示归档模式,保留文件权限、属性、软链接等;-P 表示显示迁移进度,方便查看迁移状态。

迁移完成后,原目录 /var/lib/docker 会保留一份数据,可暂时不删除,待验证修改成功后再清理(避免迁移失败无法恢复)。

步骤 3:重启 Docker 服务并验证

# 重新加载 Docker 配置(使 daemon.json 生效)
sudo systemctl daemon-reload
# 启动 Docker 服务
sudo systemctl start docker
# 查看 Docker 服务状态,确认启动成功
sudo systemctl status docker

若启动失败,可查看日志排查问题:

# 查看 Docker 启动日志(显示最近 50 行,方便定位错误)
sudo journalctl -u docker.service -n 50

启动成功后,验证新目录是否生效:

# 查看 Docker 根目录,确认已修改为新路径
docker info | grep "Docker Root Dir"

若输出 Docker Root Dir: /data/docker,则说明修改成功。

步骤 4:验证数据可用性(关键)

迁移数据后,需要验证原有镜像、容器是否正常可用:

# 查看原有镜像(应与迁移前一致)
docker images
# 查看原有容器(应与迁移前一致)
docker ps -a
# 可选:启动一个原有容器,验证是否能正常运行
docker start 容器ID/容器名
# 可选:拉取一个新镜像,验证新镜像是否存储在新目录
docker pull hello-world
# 查看新目录下是否有新增数据(应出现 containers、images、overlay2 等目录)
ls /data/docker/

若所有操作正常,说明修改和迁移均成功;若原有镜像、容器丢失,大概率是迁移步骤遗漏或权限设置错误,可重新执行迁移命令。

步骤 5:清理旧数据(可选,确认成功后执行)

验证修改成功后,原有 /var/lib/docker 目录已无用,可删除以释放系统盘空间(删除前务必再次确认新目录正常可用,避免误删):

# 备份原目录(可选,再次保险)
sudo mv /var/lib/docker /var/lib/docker.old
# 确认新目录正常后,删除原目录(彻底释放空间)
sudo rm -rf /var/lib/docker.old

方法二:软链接方式(快速临时修改)

软链接方式本质是将默认目录 /var/lib/docker 链接到新目录,Docker 实际读取和写入的是新目录,无需修改 Docker 配置文件,操作简单,适合临时修改或快速迁移场景。但缺点是若软链接被误删除,会导致 Docker 无法正常运行,稳定性略逊于方法一。

步骤 1:备份并删除原有默认目录

(前提:已停止 Docker 服务、已创建新目录 /data/docker

# 备份原有默认目录(重命名,避免误删)
sudo mv /var/lib/docker /var/lib/docker.old

步骤 2:创建软链接

将新目录 /data/docker 链接到默认路径 /var/lib/docker,Docker 会通过软链接访问新目录:

# 创建软链接,格式:ln -s 新目录 原有默认目录路径
sudo ln -s /data/docker /var/lib/docker

查看软链接是否创建成功:

# 查看软链接信息
ls -l /var/lib/docker

输出如下即为创建成功(箭头指向新目录):

lrwxrwxrwx 1 root root 11 10月 28 15:30 /var/lib/docker -> /data/docker

步骤 3:迁移原有数据(可选)

若原有目录有数据,将备份的 /var/lib/docker.old 目录下的所有内容复制到新目录:

sudo rsync -aP /var/lib/docker.old/ /data/docker/

步骤 4:重启 Docker 并验证

# 启动 Docker 服务
sudo systemctl start docker
# 查看 Docker 根目录(仍显示 /var/lib/docker,但实际指向新目录)
docker info | grep "Docker Root Dir"
# 验证镜像、容器是否正常(同方法一的验证步骤)
docker images
docker ps -a

注意:软链接创建后,请勿删除 /var/lib/docker 这个软链接文件,否则会导致 Docker 无法访问新目录。

方法三:修改 systemd 启动参数(过时,不推荐)

该方法通过修改 Docker 的 systemd 启动服务文件,添加 --graph(旧版本参数,已被 data-root 替代)或 --data-root 参数,指定新的存储目录。适用于 Docker 17.06 以下的旧版本,目前主流版本已不推荐使用,因为修改系统服务文件后,后续 Docker 升级可能会覆盖该配置,导致修改失效。

步骤 1:编辑 Docker systemd 服务文件

# 编辑 Docker 服务文件(路径固定)
sudo vim /usr/lib/systemd/system/docker.service

步骤 2:修改 ExecStart 字段

找到 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 这一行,在后面添加 --data-root /data/docker(指定新目录),修改后如下:

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root /data/docker

注意:旧版本 Docker 可能使用 --graph 参数,效果一致,但官方已弃用,优先使用 --data-root

步骤 3:重启 Docker 并验证

# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启动 Docker 服务
sudo systemctl start docker
# 验证新目录是否生效
docker info | grep "Docker Root Dir"

后续迁移数据、验证可用性的步骤,与方法一一致,此处不再重复。

三、常见问题排查(踩坑必看)

修改过程中可能会遇到 Docker 启动失败、镜像容器丢失、权限不足等问题,以下是最常见的 4 种问题及解决方案,帮大家快速定位解决。

问题 1:Docker 启动失败,日志提示 “permission denied”(权限不足)

原因:新目录权限设置错误(非 root:root 或权限不是 700),或 SELinux 未配置上下文(CentOS 系列)。

解决方案:

# 重新设置新目录权限
sudo chown root:root /data/docker
sudo chmod 700 /data/docker
# 若启用 SELinux,重新配置上下文
sudo semanage fcontext -a -t container_var_lib_t "/data/docker(/.*)?"
sudo restorecon -R /data/docker
# 重启 Docker 服务
sudo systemctl restart docker

问题 2:Docker 启动失败,日志提示 “invalid character”(JSON 格式错误)

原因:修改 daemon.json 时,JSON 格式错误(如逗号遗漏、引号不匹配、末尾多逗号)。

解决方案:

  1. 重新编辑 daemon.json,检查格式(推荐用在线 JSON 验证工具验证);
  2. 确保字段之间用逗号分隔,最后一个字段后面没有逗号;
  3. 示例正确格式:
{
  "registry-mirrors": ["https://docker.mirrors.aliyun.com"],
  "data-root": "/data/docker"
}

修改后重新加载配置并重启 Docker:

sudo systemctl daemon-reload
sudo systemctl start docker

问题 3:修改后原有镜像、容器丢失

原因:未迁移原有 /var/lib/docker 目录下的数据,或迁移过程中出现错误(如未加 -a 参数导致权限丢失)。

解决方案:

# 停止 Docker 服务
sudo systemctl stop docker
# 重新迁移数据(使用 rsync -aP 确保权限和属性保留)
sudo rsync -aP /var/lib/docker.old/ /data/docker/
# 重启 Docker 服务
sudo systemctl start docker
# 验证镜像、容器是否恢复
docker images
docker ps -a

问题 4:清理旧数据后,系统盘空间未释放

原因:原目录 /var/lib/docker.old 未彻底删除,或 Docker 进程仍占用旧目录资源。

解决方案:

# 确认 Docker 服务正常运行,且新目录生效
docker info | grep "Docker Root Dir"
# 彻底删除旧目录
sudo rm -rf /var/lib/docker.old
# 查看系统盘空间,确认释放
df -h

四、总结与最佳实践

1. 方法对比(快速选择)

方法 优点 缺点 适用场景
修改 daemon.json(推荐) 官方推荐、稳定可靠、灵活易修改、不影响系统配置 需注意 JSON 格式 所有主流 Docker 版本、长期使用、生产环境
软链接 操作简单、无需修改配置、快速迁移 稳定性差、软链接易误删 临时修改、测试环境、快速迁移
修改 systemd 启动参数 适配旧版本 Docker 官方弃用、升级 Docker 可能失效、修改系统配置 Docker 17.06 以下旧版本

2. 最佳实践建议

  1. 新服务器部署 Docker 时,建议提前规划好存储目录,安装 Docker 后立即修改默认目录,避免后期迁移数据的麻烦;
  2. 生产环境优先使用方法一(修改 daemon.json),稳定性和可维护性更高;
  3. 修改前务必停止 Docker 服务、备份数据,避免数据丢失;
  4. 定期清理 Docker 无用数据(镜像、容器、卷),释放存储空间,可执行以下命令:
# 查看 Docker 磁盘使用情况
docker system df
# 清理未使用的镜像、容器、网络(不删除卷)
docker system prune
# 清理未使用的所有数据(包括卷,谨慎使用)
docker system prune --volumes
  1. 新目录建议选择独立分区或数据盘,避免与系统盘共用,防止 Docker 数据占满系统盘,影响系统稳定性。

五、结尾

以上就是 Linux 系统修改 Docker 镜像和容器默认目录的超详细实操教程,涵盖了前期准备、三种修改方法、问题排查和最佳实践,全程实操可落地,新手也能轻松搞定。

如果在操作过程中遇到其他问题,欢迎在评论区留言,我会第一时间回复帮忙排查。觉得有用的话,记得点赞、收藏,关注我,后续分享更多 Docker 实操技巧~

内容由AI生成,仅供参考