Dockge Compose 管理体系
这是 PVE 服务整理的第三篇记录。
前两篇主要完成了底座:先把 PVE 宿主机上的职责重新分层,再单独部署 net-gateway-01 作为旁路代理网关。
这一篇继续往下走,但不是直接把所有服务一口气搬走,而是先把 Compose 管理方式整理出来。
最终目标是:
Git 仓库保存标准 ComposeDockge 作为本机可视化操作面板运行目录保存真实 .env 和实际部署文件服务数据统一放到 /data/docker这样后续迁移 Jellyfin、Navidrome、Komga、qBittorrent、Radarr 这些更重的服务时,不会把 PVE 上的历史混乱一起搬过去。
当前目标
在前一阶段结束时,infra-docker-01 已经能正常运行 Docker,并且可以通过 net-gateway-01 访问 Docker Hub。
这一阶段要解决的问题变成了:
Compose 文件放在哪里Dockge 管理哪些目录真实 .env 怎么保存哪些内容可以进公开 Git 仓库服务配置和数据怎么统一放置第一个标准化服务如何落地这次不追求迁移数量,而是先把流程跑通。
设计原则
这次没有继续沿用 1Panel 的目录结构,也没有让 Dockge 成为唯一配置来源。
最后确定的关系是:
Git 仓库 = Compose 配置资产中心 / Source of TruthDockge = 每台 Docker 主机上的本地操作面板Docker Compose = 原生运行格式未来自研平台 = 读取 Git,再调用 Docker / SSH / API这里最关键的是第一行:Git 才是事实来源。
Dockge 很适合做本机可视化管理,可以启动、停止、查看日志,也能直接编辑 stack。但如果所有配置只留在 Dockge 的运行目录里,后面换面板、扩展多服务器、做备份和审计都会比较难受。
所以我更希望每个服务都整理成一个标准 Stack:
stacks/<service>/compose.yamlstacks/<service>/.env.examplestacks/<service>/README.md真实运行时再放到:
/data/compose/stacks/<service>/compose.yaml/data/compose/stacks/<service>/.env这样即使用不上 Dockge,也可以直接进入目录执行:
docker compose configdocker compose up -d节点与存储
新的 Docker 服务节点仍然是:
Hostname: infra-docker-01IP: 192.168.3.30系统: Debian GNU/Linux 13 trixie虚拟化: KVM内存: 约 12G这台 VM 有系统盘和数据盘。这里有一个重要修正:一开始考虑过把 Docker Engine 的数据目录迁到 /data/docker-engine,但后来确认 /data 是机械硬盘,所以放弃了这个方案。
最终规划是:
/var/lib/docker 保持默认,继续放在系统盘/data/compose 放 compose 文件、Git 仓库、Dockge stacks/data/docker 放应用配置、数据、缓存、备份/data/media 后续作为媒体挂载入口原因很直接:Docker 的 overlay2、镜像层、容器可写层、日志和小文件随机 IO 比较多,不适合整体放到机械硬盘上。
机械硬盘更适合放这些内容:
媒体文件下载文件应用配置低频数据备份文件而不是 Docker Engine 的运行层。
目录结构
最终在 infra-docker-01 上整理出的目录结构是:
/data/├── compose/│ ├── stacks/ # Dockge 实际管理的运行目录│ └── repo/ # Git 仓库目录│├── docker/│ ├── config/ # 服务配置│ ├── data/ # 应用数据│ ├── cache/ # 缓存│ └── backups/ # 备份│└── media/ ├── anime/ ├── movie/ ├── music/ └── manga/几个路径的职责要分清楚:
| 路径 | 用途 |
|---|---|
/data/compose/stacks | Dockge 管理和运行 stack 的目录 |
/data/compose/repo/homelab-compose | Git 仓库工作目录 |
/data/docker/config/<service> | 服务配置目录 |
/data/docker/data/<service> | 服务数据目录 |
/data/docker/cache/<service> | 缓存目录 |
/data/docker/backups | 后续备份目录 |
这样以后看一个服务时,基本可以按同一个模式找:
Compose 标准版:/data/compose/repo/homelab-compose/stacks/<service>Compose 运行版:/data/compose/stacks/<service>配置和数据:/data/docker/config/<service>部署 Dockge
Dockge 被作为第一个 stack 部署在:
/data/compose/stacks/dockge挂载的关键内容是:
/var/run/docker.sock/data/compose/stacks/data/docker/config/dockge对外端口:
http://192.168.3.30:5001启动后容器状态正常:
dockge louislam/dockge:1 Up healthy日志里也能看到:
Welcome to dockge!Connected to the databaseNo user, need setupListening on 5001这说明 Dockge 已经可以作为 infra-docker-01 本机的 Compose 管理面板使用。
这里也要注意一点:Dockge 需要挂载 Docker socket,意味着它对本机 Docker 有很高权限,所以不应该直接暴露到公网。
创建 homelab-compose 仓库
为了让 Compose 配置可以长期维护,我在 infra-docker-01 上创建了:
/data/compose/repo/homelab-compose仓库骨架如下:
homelab-compose/├── docs/│ ├── hosts.md│ ├── networks.md│ └── storage.md├── hosts/│ ├── infra-docker-01/│ │ └── stacks/│ ├── net-gateway-01/│ └── pve/│ └── stacks/├── scripts/├── stacks/│ └── dockge/│ ├── compose.yaml│ └── README.md├── templates/│ ├── compose.template.yaml│ └── env.example├── .gitignore└── README.md几个目录的用途:
| 目录 | 用途 |
|---|---|
docs/ | 记录主机、网络和存储规划 |
hosts/ | 预留按主机组织的配置入口 |
stacks/ | 保存标准化后的公开 compose |
templates/ | 保存通用模板 |
scripts/ | 保存部署、检查等辅助脚本 |
这个仓库未来准备开源,所以从一开始就不能把真实密钥、真实 .env、原始 PVE compose 或未脱敏配置放进去。
开源安全边界
一开始我考虑过把 PVE 上的原始 Compose 做一份 raw-stacks 快照放进仓库,方便后续参考。后来这个方案被否掉了。
原始 Compose 里可能存在:
硬编码密钥tokenaccess key / secret key真实内网路径真实服务端口代理地址私有域名下载器、索引器、对象存储等敏感配置如果仓库未来要公开,这些内容不能混进去。
最后的边界是:
公开仓库: 只放脱敏后的标准 compose、README、.env.example、模板和脚本
真实运行目录: 放本机 .env 和实际 compose
私有快照目录: 放在仓库外,例如 /data/compose/private,不进入 Git同时 .gitignore 里排除:
.env*.env*.secretsecrets/private/raw/raw-stacks/hosts/**/raw-stacks/*.local.yml*.raw.yml这一步比多迁移几个服务更重要。因为它决定了这个仓库以后能不能安全公开、能不能被长期维护。
标准版与运行版分离
整理后,每个服务会同时存在两个形态。
Git 仓库里的标准版:
/data/compose/repo/homelab-compose/stacks/<service>/compose.yaml/data/compose/repo/homelab-compose/stacks/<service>/.env.example/data/compose/repo/homelab-compose/stacks/<service>/README.md运行目录里的实际版本:
/data/compose/stacks/<service>/compose.yaml/data/compose/stacks/<service>/.env服务数据统一放到:
/data/docker/config/<service>/data/docker/data/<service>/data/docker/cache/<service>这样有几个好处:
- Git 里可以安全保存标准模板;
.env留在本机,不进入公开仓库;- Dockge 可以管理
/data/compose/stacks; - 不依赖 Dockge 的私有结构;
- 后续可以用脚本或自研平台读取 Git,再部署到不同主机。
部署脚本
为了减少手工复制文件,我写了一个辅助脚本:
scripts/deploy-stack.sh使用方式:
./scripts/deploy-stack.sh <stack-name>它主要做三件事:
- 从 Git 仓库的
stacks/<stack-name>复制compose.yaml到/data/compose/stacks/<stack-name>; - 如果运行目录没有
.env,就从.env.example创建; - 不自动启动服务,只提示下一步执行
docker compose config和docker compose up -d。
这里故意不自动启动服务。
因为部署脚本应该先帮我减少重复动作,而不是替我跳过确认步骤。尤其是这种自托管服务迁移,启动前最好先检查一次最终 Compose:
docker compose config确认没有路径、端口、变量问题后,再启动:
docker compose up -d第一个样板:FlareSolverr
第一个标准化服务选择 flaresolverr。
原因是它足够简单:
基本无状态不涉及媒体库不涉及下载路径不需要复杂联动适合验证 Git + Dockge + Compose 工作流路径规划:
Git 仓库:/data/compose/repo/homelab-compose/stacks/flaresolverr运行目录:/data/compose/stacks/flaresolverr配置目录:/data/docker/config/flaresolverr运行端口:
192.168.3.30:8191旧 PVE 上的 FlareSolverr 使用过类似这样的代理地址:
PROXY=http://172.18.0.1:20172这类地址绑定的是 PVE 上的 Docker bridge,不适合照搬到新节点。
新的标准化版本改为通过 .env 配置:
FLARESOLVERR_PROXY=http://192.168.3.20:7890也就是让它走 net-gateway-01 提供的显式代理。
启动后日志显示:
FlareSolverr 3.5.0Testing web browser installation...Chrome / Chromium path: /bin/chromiumTest successful!Serving on http://0.0.0.0:8191测试返回:
HTTP/1.1 200 OK这说明第一个标准化服务已经在新节点上跑通。
第二个样板:Prowlarr
第二个服务选择 prowlarr。
它比 Jellyfin、qBittorrent、Radarr 更轻,只需要先处理 /config,不直接涉及大容量媒体目录。
路径规划:
Git 仓库:/data/compose/repo/homelab-compose/stacks/prowlarr运行目录:/data/compose/stacks/prowlarr配置目录:/data/docker/config/prowlarr运行端口:
192.168.3.30:9696启动后容器状态正常:
prowlarr lscr.io/linuxserver/prowlarr:latest Up日志显示:
Now listening on: http://[::]:9696Application started.Hosting environment: Production本机测试:
curl -I http://127.0.0.1:9696返回:
HTTP/1.1 401 Unauthorized这里的 401 不是错误,而是 Prowlarr 的认证机制在工作。服务已经监听端口,只是访问 Web 或 API 需要认证。
到这一步,我也确定了一个后续原则:大多数旧服务不再完整迁移旧配置,而是在新环境中重新配置。
旧配置里有不少历史路径、代理地址和临时改动,强行迁移容易把问题一起带过去。既然这次本来就是整理,就不如借机会把配置重新规范化。
第三个样板:Sun Panel
第三个服务选择 sun-panel。
它不涉及媒体库,也不依赖下载器和索引器联动,适合作为第三个干净服务样板。
路径规划:
Git 仓库:/data/compose/repo/homelab-compose/stacks/sun-panel运行目录:/data/compose/stacks/sun-panel配置目录:/data/docker/config/sun-panel运行端口:
192.168.3.30:3002这个服务有一个特殊点:它挂载了 Docker socket。
/var/run/docker.sock这意味着它访问的是 infra-docker-01 本机 Docker,而不是 PVE 上的 Docker。这个行为符合新规划,因为现在要管理的是新 Docker 节点上的服务。
但同样需要注意:挂载 Docker socket 的服务权限很高,不应该直接暴露到公网。
目前 sun-panel 已经正常运行。
当前成果
这一阶段完成后,infra-docker-01 上已经有四个服务按新方式运行:
| 服务 | 地址 | 状态 |
|---|---|---|
| Dockge | http://192.168.3.30:5001 | healthy |
| FlareSolverr | http://192.168.3.30:8191 | 正常 |
| Prowlarr | http://192.168.3.30:9696 | 正常,访问需认证 |
| Sun Panel | http://192.168.3.30:3002 | 正常 |
同时也完成了这些基础工作:
1. 确定 Git 作为 Compose Source of Truth2. 确定 Dockge 只作为本地操作面板3. 规划 /data/compose、/data/docker、/data/media4. 建立 homelab-compose 仓库骨架5. 明确公开仓库和真实运行配置的边界6. 编写 deploy-stack.sh 辅助部署脚本7. 标准化 FlareSolverr、Prowlarr、Sun Panel 三个服务这次维护的重点不是“又多跑了几个容器”,而是 Compose 管理方式变清楚了。
以前是:
服务散落在 PVE 宿主机1Panel 与手写 Compose 混用路径和网络配置不统一代理地址硬编码配置来源不清楚现在变成:
Git 保存标准 ComposeDockge 管理本机运行目录.env 留在本机配置和数据进入统一目录每个服务都可以单独部署、停止、重建这对后续迁移更重要。因为后面的服务会更麻烦:媒体库、下载目录、硬链接、对象存储、反向代理、硬件转码都会逐步出现。
如果没有先把管理体系整理好,后面每迁一个服务都会继续扩大混乱。
后续计划
下一阶段仍然不建议一口气全搬。
比较适合继续处理的顺序是:
1. Navidrome2. Komga3. Suwayomi4. Radarr5. qBittorrent6. AutoBangumi7. Jellyfin8. RustFS9. Jenkins10. OpenResty / 入口层其中需要特别谨慎的是:
| 服务 | 风险点 |
|---|---|
| qBittorrent | 下载路径、端口、host 网络、硬链接 |
| Radarr | 媒体路径、下载器联动 |
| Jellyfin | 媒体库、硬件转码 |
| RustFS | 对象存储数据 |
| OpenResty | 入口流量,不适合太早迁移 |
后续原则还是保持不变:
先让服务干净跑起来再重新配置不强行迁移旧配置不把敏感信息写入 Git不急着停掉 PVE 上旧服务到这里,PVE 服务迁移已经从“建新 VM”和“解决网络”进入到“整理服务资产”的阶段。
这一步看起来没有直接迁移重服务,但它决定了后续每个服务能不能按同一套方式落地。对家用服务器来说,能跑只是第一步,能长期维护才是更重要的部分。