飞牛 OS + 1Panel:Docker 数据目录迁移全记录

飞牛 OS + 1Panel:Docker 数据目录迁移全记录

__

环境: 飞牛 OS(fnOS,基于 Debian)+ 1Panel v2.2.1 + Docker
目标: 将 Docker 数据从系统盘迁移至数据盘,彻底释放系统盘空间
结果: 系统盘占用从 41%(11G)降至 25%(6.3G),释放约 5G


一、背景与起因

在飞牛 OS 上通过 1Panel 管理 Docker 应用(Halo 博客、Nginx Proxy Manager、frpc、MCSManager 等),运行一段时间后发现系统盘空间持续增长,担心未来被写满引发服务中断,而且中途已经发生过一次系统盘占用拉满的情况了。

飞牛 OS 的存储架构

飞牛 OS 采用系统盘与数据盘物理分离的设计:

  • 系统盘/dev/mmcblk0p2):28G eMMC,挂载于 /,用于系统文件
  • 数据盘 /vol1:120G,飞牛 OS 原本规划的 Docker 存储位置
  • 数据盘 /vol2:205G,其他数据存储

问题根源

通过排查发现,飞牛 OS 原本将 Docker 数据存放在 /vol1/docker,但 1Panel 安装后将 Docker 的 data-root 重置回了默认的 /var/lib/docker(系统盘),导致之后所有新拉取的镜像、容器层都写入系统盘,而 /vol1/docker 里只保留了飞牛 OS 时代的旧镜像。

# 排查命令:确认 Docker 实际使用的目录
sudo docker info | grep "Docker Root Dir"
# 输出:Docker Root Dir: /var/lib/docker  ← 在系统盘,问题所在

# 查看各目录占用
sudo du -sh /var/lib/docker/overlay2   # 镜像层,最大头(显示 16G,实际因硬链接约 10G)
sudo du -sh /var/lib/docker/volumes    # Docker 管理的卷
sudo du -sh /opt/1panel/apps           # 1Panel 应用数据(bind mount)

关于 du 显示 16G 但系统盘只用 11G 的原因

du 统计文件内容大小,overlay2 中大量使用了硬链接——多个镜像层共享同一文件,du 会对每个硬链接都计一遍,导致数值虚高。实际磁盘占用以 df 为准。


二、核心操作:修改 Docker data-root

解决思路

只需将 daemon.json 中的 data-root 指回飞牛 OS 原本规划的 /vol1/docker,不需要重装 1Panel,不需要迁移任何数据。

操作步骤

第一步:停止 1Panel 和 Docker

sudo 1pctl stop
sudo systemctl stop docker
sudo systemctl stop docker.socket
sudo systemctl stop docker   # 再执行一次确保完全停止

⚠️ 注意:飞牛 OS 的 1Panel 不能用 systemctl stop 1panel,要用 1pctl stop

第二步:修改 daemon.json,加入 data-root

# 先查看现有配置,保留原有镜像源配置
sudo cat /etc/docker/daemon.json

# 写入新配置(保留原有镜像源,加入 data-root)
sudo tee /etc/docker/daemon.json > /dev/null << 'EOF'
{
        "registry-mirrors": [
                "https://docker.1panel.live",
                "https://proxy.1panel.live",
                "https://docker.m.daocloud.io",
                "https://docker.nju.edu.cn",
                "https://mirror.iscas.ac.cn"
                // 保留你原有的所有镜像源
        ],
        "data-root": "/vol1/docker"
}
EOF

# 验证 JSON 格式正确
sudo cat /etc/docker/daemon.json | python3 -m json.tool

第三步:启动 Docker 并验证

sudo systemctl start docker

# 必须确认路径已切换
sudo docker info | grep "Docker Root Dir"
# 应输出:Docker Root Dir: /vol1/docker

# 确认容器和镜像可见
sudo docker ps -a
sudo docker images

第四步:启动 1Panel

sudo 1pctl start

三、踩到的坑与处理方式

坑 1:1panel-network 网络丢失,Halo 无法连接 PostgreSQL

现象: 切换 data-root 后,Halo 启动报错:

Caused by: java.net.UnknownHostException: postgresql
Cannot connect to postgresql/<unresolved>:5432

原因: Docker 切换 data-root 后,原来在 /var/lib/docker 里的 1panel-network 自定义网络配置丢失,容器之间无法通过容器名互相解析。

处理方式:

# 确认网络是否存在
sudo docker network ls | grep 1panel

> ⚠️ 注意:如果网络存在,但是依然无法打开应用的web界面的话可以重启机器再试试。

# 如果不存在,重新创建,如果存在,不执行此步骤
sudo docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  1panel-network

然后在 1Panel 应用商店 → 已安装,对所有应用点**「重建」**(注意是重建不是重启),让容器重新加入网络。

✅ 本次操作中 1panel-network 实际上已经在 /vol1/docker 里存在,直接启动 1Panel 后网络自动恢复,未受影响。


坑 2:部分应用镜像丢失,重建时需要重新拉取

现象: NPM、Hermes 等应用点重建后一直卡住,或提示找不到镜像。

原因: 这些镜像是在 1Panel 安装后才拉取的,存在系统盘 /var/lib/docker 里,切换到 /vol1/docker 后自然看不到了。/vol1/docker 里只有飞牛 OS 时代的旧镜像(包括一些早已"卸载"但镜像残留的应用,如 qwrt)。

处理方式:

在 1Panel 界面 → 容器 → 镜像 → 手动拉取缺失的镜像,利用已配置的加速源下载。镜像拉取完成后再启动对应应用。

优先从1panel界面拉取镜像,拉取成功之后,正常情况可以在应用界面直接启动应用。

# 也可以命令行直接启动,会自动拉取镜像
cd /opt/1panel/apps/nginx-proxy-manager/nginx-proxy-manager
sudo docker compose up -d

cd /opt/1panel/apps/hermes-agent/Hermes-Agent
sudo docker compose up -d

💡 更优方案(如果网络好): 切换前先把系统盘的新镜像 rsync 合并到 /vol1/docker,避免重新下载:

sudo rsync -aHAX /var/lib/docker/ /vol1/docker/

本次因为数据量不大、网络速度可接受,选择了直接重新拉取。


坑 3:NPM 重建卡死,容器未创建成功,该情况是应用镜像丢失导致的

现象: 1Panel 界面显示"重建中"但长时间没有进度,docker ps -a 里找不到 NPM 容器。

处理方式: 绕过 1Panel 的重建流程,直接用 docker compose 手动启动:

# 找到 compose 文件位置
sudo find /opt -name "docker-compose.yml" 2>/dev/null | grep nginx

# 直接启动
cd /opt/1panel/apps/nginx-proxy-manager/nginx-proxy-manager
sudo docker compose up -d

坑 4:系统盘旧 Docker 数据未自动清理

现象: 切换完成后 df -h / 显示系统盘占用没有变化,还是 11G。

原因: /var/lib/docker 旧目录不会自动删除,需要手动清理。

处理方式: 确认所有应用正常运行后再删除:

# 确认 Docker 路径已切换
sudo docker info | grep "Docker Root Dir"
# 确认应用全部正常
sudo docker ps --format "table {{.Names}}\t{{.Status}}"

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

# 清理悬空镜像
sudo docker image prune -f

坑 5:iptv-spider 等通过 yml 手动创建的容器报 warning,同样是镜像丢失导致的问题,拉取镜像即可在容器的编排界面启动

现象:

the attribute `version` is obsolete, it will be ignored

原因: Docker Compose v2 已废弃 version 字段,这只是一个警告,不影响容器启动,可以忽略或删除 compose 文件里的 version: '3' 那行。


四、最终结果

迁移前:
  系统盘:28G 总量,已用 11G,使用率 41%
  Docker Root Dir: /var/lib/docker(系统盘)

迁移后:
  系统盘:28G 总量,已用 6.3G,使用率 25%(释放约 5G)
  Docker Root Dir: /vol1/docker(数据盘)
  /vol1:120G 总量,已用 12G,使用率 10%

所有应用恢复正常运行:frpc、NPM、Halo、PostgreSQL、MCSManager(daemon+web)、pgAdmin4、Hermes-Agent、iptv-spider。


五、注意事项与后续维护

⚠️ 重要:升级后检查 data-root 是否被重置

1Panel 升级或飞牛 OS 系统升级后,daemon.json 有可能被覆盖,导致 data-root 回退到默认的 /var/lib/docker

每次升级后必须执行一次检查:

sudo docker info | grep "Docker Root Dir"

如果显示 /var/lib/docker 而不是 /vol1/docker,说明被重置了,重新修改 daemon.json 并重启 Docker:

# 在 daemon.json 里重新加入 data-root
sudo vim /etc/docker/daemon.json
# 加入:"data-root": "/vol1/docker"

sudo systemctl restart docker
sudo 1pctl restart

建议备份一份配置:

sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.backup

定期清理 Docker 无用资源

# 清理悬空镜像(无标签、无容器引用的镜像层)
sudo docker image prune -f

# 更激进:清理所有未使用的镜像、容器、网络、缓存
sudo docker system prune -f

监控系统盘使用率

# 快速查看关键分区
df -h / /vol1 /vol2

六、FAQ

Q:重建应用会丢数据吗?
A:不会。重建只是重新创建容器(docker rm + docker run),数据卷是 bind mount 到宿主机目录的,容器删了数据还在原地,重建后重新挂载回来,完整无损。

Q:飞牛 OS 自带的 Docker 图形界面和 1Panel 会冲突吗?
A:不会。两者共用同一个 dockerd 进程,只是管理界面不同。修改 daemon.json 后两边都生效,飞牛 OS 的 Docker 面板也会同步显示新路径下的容器和镜像。

Q:为什么不直接把 1Panel 也装到数据盘?
A:可以,重装时加 --base-dir /vol1/1panel 参数即可。但 /opt/1panel/apps 下存的主要是应用配置文件(compose、env 等),体积很小(本案例约 700M),相比镜像的十几 G 影响不大。如果系统盘实在紧张,可以后续再做这一步。

Q:du 显示 overlay2 有 16G 但系统盘只用了 11G,正常吗?
A:正常。overlay2 大量使用硬链接,多个镜像层共享同一文件,du 会重复计算每个硬链接,导致数值虚高。实际占用以 df 显示的为准。


七、相关命令速查

# 查看 Docker 数据目录
sudo docker info | grep "Docker Root Dir"

# 查看磁盘占用
df -h /
df -h /vol1

# 停止/启动 1Panel(飞牛 OS 环境)
sudo 1pctl stop
sudo 1pctl start
sudo 1pctl status

# 停止/启动 Docker
sudo systemctl stop docker.socket && sudo systemctl stop docker
sudo systemctl start docker

# 查看所有容器状态
sudo docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

# 手动启动应用(绕过 1Panel 重建)
cd /opt/1panel/apps/<应用名>/<应用名>/
sudo docker compose up -d

# 查看容器日志
sudo docker logs <容器名> --tail 50

# 清理无用镜像
sudo docker image prune -f

香橙派 OrangePi AI Pro 20T 接入 0.96寸 OLED 小屏幕 2026-05-20
思源笔记 MCP 接入 Hermes-Agent 完整排查总结 2026-06-20

评论区