Skip to content

Roadmap: Multi-host GitOps Compose management and safe container update orchestration #2

Description

@YangYuS8

背景

Astralith v1.0.0 已经具备 AI-native GitOps control plane 的核心原型:GitOps 仓库配置、Desired Resource 解析、Actual Resource 写入、Desired / Actual diff、Apply Plan、Policy Result、Docker Compose Apply Run、AI Proposal 与 Operation Module Proposal。

但当前 v1.0.0 的 GitOps / Docker Compose 能力仍然偏 MVP / 演示闭环:

  • GitOps Apply 目前主要使用本地 localhost inventory 演示执行,还没有真正根据 stack.yaml 选择受管主机。
  • Desired State 的 YAML 解析还是简单 key/value parser,不支持真实 Compose 管理所需的嵌套结构。
  • Actual Resource 主要靠 API upsert,缺少自动扫描目标主机 Docker Compose 状态的能力。
  • Diff 主要覆盖 create / update,尚未完整覆盖 desired 缺失但 actual 存在的 orphan / delete candidate 场景。
  • Policy validation 已有框架,但规则仍较浅,尚未真正解析 compose.yaml 并检测 privileged、host network、危险挂载、公开端口、latest 镜像等风险。
  • 容器镜像更新策略仍停留在设计阶段,尚未和 GitOps Apply、备份、健康检查、回滚、审计记录形成完整编排。

在整理 homelab / Docker Compose 管理方案时,原本考虑引入 Watchtower 之类的自动更新器,用于让低风险容器自动获取新镜像,从而更快获得安全修复。

但后续发现 containrrr/watchtower 上游已经归档,且在 Docker 29.x 环境下还出现过 Docker API 版本兼容问题。因此,不希望把一个缺乏未来维护承诺的项目作为新架构的核心依赖。

这件事可以转化为 Astralith 后续的重要能力方向:

由 Astralith 自己围绕 GitOps desired state,实现多主机 Docker Compose 管理、实际状态扫描、风险策略校验、镜像更新检测、人工审批、备份、健康检查、回滚和审计记录,而不是简单依赖无人值守自动更新器。


新定位

本 issue 是 issue #1 之后的落地路线,重点从“AI-native GitOps 控制平面原型”推进到:

真实多主机 GitOps Compose 管理
+ Actual State 自动扫描
+ Compose Policy Engine
+ 安全可控的容器镜像更新编排

目标不是简单做到:

发现新镜像 -> 立即 pull -> 重启容器

而是做到:

Git 仓库声明 Stack 与更新策略
  ↓
Astralith 同步 Desired State
  ↓
扫描目标主机 Actual State
  ↓
生成 Desired / Actual Diff
  ↓
解析 Compose 并执行 Policy Validation
  ↓
生成 Apply Plan / Update Plan
  ↓
人工审批
  ↓
备份关键配置 / 数据
  ↓
拉取新镜像或切换目标 digest
  ↓
重建容器
  ↓
执行健康检查
  ↓
成功则记录变更
  ↓
失败则回滚并记录原因

设计原则

  1. Git 仍然是期望状态来源。 Stack 定义、更新策略、备份策略、健康检查策略、回滚策略应尽量声明化。
  2. 不做无脑 Watchtower 替代品。 Astralith 不应该默认无人值守更新所有容器。
  3. 更新必须经过风险分级。 不同服务允许不同策略:auto / notify / manual / frozen。
  4. 入口层、数据库、对象存储、下载器、管理面板自身默认不自动更新。
  5. 所有执行必须通过 Ansible Runner / Docker Compose 受控服务层。 不绕过平台直接执行任意 shell。
  6. 所有高风险更新必须人工审核。 尤其是 major upgrade、数据库迁移、volume 变更、网络模式变更。
  7. 更新前必须能解释回滚方式。 没有回滚路径的服务不能进入自动更新候选。
  8. AI 只辅助生成说明、风险解释、Runbook 或 Update Proposal,不直接执行更新。
  9. 先把 GitOps 多主机闭环做实,再做自动更新。 容器更新编排不能建立在 localhost demo apply 上。

Desired State Schema 草案

Host 声明

# hosts/monitoring-01.yaml
name: monitoring-01
address: 192.168.3.41
ssh_user: root
ssh_port: 22
private_key_path: /keys/monitoring-01
tags:
  - pve
  - monitoring
  - docker

说明:

  • private_key_path 只保存路径,不保存私钥内容。
  • 后续可选择同步为 Host 表记录,也可只作为 GitOps desired resource 展示。
  • Apply 时应能根据 target_host 查找到对应 Host / inventory。

Stack 声明

# stacks/uptime-kuma/stack.yaml
name: uptime-kuma
target_host: monitoring-01
project_name: uptime-kuma
stack_path: /opt/stacks/uptime-kuma
compose_file: compose.yaml
risk_level: low
update_policy: notify
backup_policy: config_only
healthcheck:
  type: http
  url: http://127.0.0.1:3001
  expected_status: 200
rollback:
  strategy: previous_compose_and_digest

Compose 文件

# stacks/uptime-kuma/compose.yaml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:1.23.16
    restart: unless-stopped
    volumes:
      - ./data:/app/data
    ports:
      - "3001:3001"
    labels:
      dev.nesoriel.update.policy: "notify"
      dev.nesoriel.risk.level: "low"

更新策略分级

建议将服务分为四类。

Class A:Auto Candidate,可自动更新候选

适合对象:

  • 无状态服务。
  • 可快速重建的辅助服务。
  • 损坏后影响较小的工具类服务。
  • 有明确健康检查和回滚策略的服务。

示例:

  • flaresolverr
  • 小型 dashboard / helper service
  • 临时工具类容器

策略:

  • 可使用稳定分支 tag,谨慎允许 latest。
  • 必须具备健康检查。
  • 必须有可执行回滚策略。
  • 初期仍建议人工确认,后续才允许自动执行。

Class B:Notify / Semi-auto,仅提醒或半自动更新

适合对象:

  • 有本地配置数据库。
  • 不是基础入口服务。
  • 更新失败影响可控,但仍需要人工确认。

示例:

  • prowlarr
  • radarr
  • sonarr
  • lidarr
  • autobangumi
  • komf
  • suwayomi
  • navidrome
  • komga

策略:

  • 平台检测更新并提醒。
  • 用户确认后执行。
  • major upgrade 前建议备份配置目录。
  • 更新后执行容器状态、端口、HTTP 或日志关键字检查。

Class C:Manual,仅手动更新

适合对象:

  • 入口层。
  • 对象存储。
  • 下载器。
  • CI/CD。
  • 数据核心服务。
  • 管理面板自身。

示例:

  • jellyfin
  • qbittorrent
  • rustfs
  • jenkins
  • openresty / reverse proxy
  • dockge / komodo / astralith
  • database

策略:

  • 不允许无人值守自动更新。
  • 更新前必须备份。
  • 建议阅读 release notes。
  • 需要维护窗口、健康检查和回滚计划。

Class D:Frozen,冻结更新

适合对象:

  • 当前版本已经稳定,升级收益不明确。
  • 上游频繁破坏兼容性。
  • 正在排查问题,不希望引入变量。
  • 依赖旧 API / 旧配置格式。

策略:

  • 不自动检测或只低频检测。
  • UI 明确显示“冻结原因”。
  • 解除冻结需要人工操作。

中立元数据标签

为了避免绑定 Watchtower 等具体工具,可以在 Compose 中使用 Astralith 自己的中立 label。

labels:
  dev.nesoriel.update.policy: "manual"
  dev.nesoriel.risk.level: "medium"

建议枚举值:

auto    - 未来允许平台自动更新,但必须具备备份、健康检查、回滚能力
notify  - 只提醒用户有新版本,不自动执行更新
manual  - 必须人工确认并手动更新
frozen  - 冻结更新,除非用户主动解除

示例:

services:
  flaresolverr:
    image: ghcr.io/flaresolverr/flaresolverr:latest
    labels:
      dev.nesoriel.update.policy: "auto"
      dev.nesoriel.risk.level: "low"
services:
  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    labels:
      dev.nesoriel.update.policy: "notify"
      dev.nesoriel.risk.level: "medium"
services:
  reverse-proxy:
    image: openresty/openresty:1.25.3.2-alpine
    labels:
      dev.nesoriel.update.policy: "manual"
      dev.nesoriel.risk.level: "high"

平台需要支持的核心能力

1. 正式 Desired State Parser

当前简单 key/value parser 不足以支撑真实 GitOps Compose 管理。后续应引入 PyYAML 或同类库,支持:

  • 嵌套 YAML。
  • list / dict。
  • Stack metadata。
  • Host metadata。
  • Policy metadata。
  • Compose file parsing。

验收:

  • 能解析 hosts/*.yamlstacks/*/stack.yamlstacks/*/compose.yaml
  • 能读取 target_hoststack_pathcompose_fileupdate_policyhealthcheckrollback 等字段。

2. 真实多主机 GitOps Apply

当前 Apply 不应继续停留在 localhost demo。后续应实现:

stack.target_host
  ↓
查找 Host / desired host
  ↓
生成 Ansible inventory
  ↓
远程创建 stack_path
  ↓
同步 compose.yaml
  ↓
执行 docker compose config / pull / up -d
  ↓
保存执行结果

验收:

  • Git 中声明 target_host: monitoring-01
  • Astralith 可以在 monitoring-01 上创建 /opt/stacks/<stack> 并部署服务。
  • Apply Run 记录目标主机、路径、commit SHA、stdout、stderr、raw events、rollback metadata。

3. Actual State Scanner

Actual Resource 不应主要依赖手动 upsert。平台需要只读扫描目标主机:

建议采集:

docker compose ls --format json
docker ps --format json
docker images --digests --format json
find /opt/stacks -maxdepth 2 -name compose.yaml
sha256sum /opt/stacks/*/compose.yaml

扫描结果写入:

ActualResource
- host
- stack
- compose_file
- running_container
- image_digest
- exposed_port
- volume

验收:

  • 用户点击 Scan Actual State。
  • 平台通过 Ansible Runner 读取目标主机 Docker / Compose 状态。
  • 生成或更新 Actual Resources。

4. Desired / Actual Diff 完整化

当前 diff 应补齐 orphan / delete candidate 场景。

需要支持:

create: desired exists, actual missing
update: desired exists, actual exists, hash differs
in_sync: desired exists, actual exists, hash same
delete_candidate / orphaned: actual exists, desired missing

默认策略:

  • 不自动删除 orphan。
  • UI 标记为 orphaned resource。
  • 可生成人工确认的 stop / archive / remove plan。

验收:

  • Git 删除某个 stack 后,平台能识别目标主机上仍存在的 stack。
  • 生成 orphan warning,而不是静默忽略。

5. Compose Policy Engine

Policy validation 应真正解析 compose.yaml,而不是只看 stack.yaml 的单个 image 字段。

初期规则:

  • 禁止或高危标记 privileged: true
  • 高危标记 network_mode: host
  • 高危标记 pid: host
  • 高危标记挂载 /var/run/docker.sock
  • 禁止直接挂载 //etc/boot 等关键路径。
  • 标记 :latest 镜像。
  • 标记没有 restart 策略的长期服务。
  • 标记公开端口 0.0.0.0 暴露。
  • 数据库类服务缺少 volume 时阻断。
  • .env、私钥、token、password 字段疑似进入 Git 时阻断。

验收:

  • 危险 Compose 配置会生成 PolicyResult。
  • 高危规则阻断 Apply Plan。
  • 中低风险规则提示人工复核。

6. 镜像更新检测

需要支持:

  • 读取 compose.yaml 中的 image。
  • 查询远端 registry。
  • 判断 tag / digest 是否变化。
  • 记录当前运行镜像 digest。
  • 记录 desired image 与 actual image digest。
  • 区分 pinned tag、floating tag、latest。

初期可以先做 digest 检测,不急着做 semantic version 分类。

验收:

  • 平台展示每个服务当前 digest 与远端 digest。
  • 远端 digest 变化时生成 Update Candidate。
  • latest / floating tag 服务明确标记风险。

7. Update Plan 生成

执行前生成结构化更新计划。

示例:

Stack: flaresolverr
Host: infra-docker-01
Current image: ghcr.io/flaresolverr/flaresolverr@sha256:old
New image: ghcr.io/flaresolverr/flaresolverr@sha256:new
Policy: auto
Backup: not required
Health check: HTTP GET / on port 8191
Rollback: previous digest / previous compose commit
Risk: low

Update Plan 应包含:

  • 目标 host / stack / service。
  • 当前 image / digest。
  • 目标 image / digest。
  • 更新策略。
  • 风险等级。
  • 备份计划。
  • 健康检查计划。
  • 回滚计划。
  • 审批状态。

8. Backup Plan

针对不同服务支持不同备份策略:

  • none:无状态服务,不备份。
  • config_only:备份 /config 或项目配置目录。
  • sqlite:备份 SQLite 数据库。
  • metadata_only:只备份元数据,不备份大媒体库。
  • snapshot_required:需要 PVE / 文件系统快照,平台只提示或调用外部脚本。
  • custom_command:后续可扩展,但必须受控且人工审核。

验收:

  • Update Plan 能显示备份策略。
  • manual / high-risk 服务没有备份策略时不能进入执行。

9. Health Check

更新后执行:

  • 容器状态检查。
  • Docker healthcheck 状态。
  • 端口检查。
  • HTTP 状态检查。
  • 日志关键字检查。
  • 自定义只读命令检查。

验收:

  • 健康检查失败时 Apply / Update Run 标记 failed。
  • 平台给出失败证据。
  • 后续可触发 rollback plan。

10. Rollback Plan

如果更新失败:

  • 停止新容器。
  • 切回旧 image digest 或上一 commit 的 compose 文件。
  • 恢复配置备份。
  • 重新启动服务。
  • 再次执行健康检查。
  • 记录失败原因和回滚结果。

验收:

  • 每次 Update Plan 都能解释 rollback strategy。
  • 没有 rollback strategy 的高风险服务不允许自动更新。

11. Audit Log

每次更新都应该记录:

  • 更新时间。
  • 操作人 / 触发来源。
  • Git commit SHA。
  • 目标主机。
  • 目标 stack / service。
  • 旧镜像与 digest。
  • 新镜像与 digest。
  • 备份结果。
  • 健康检查结果。
  • 是否成功。
  • 是否回滚。
  • stdout / stderr / raw events。

数据模型草案

在已有 GitOps 表基础上,后续可增加:

compose_stacks
- id
- repository_id
- host_id
- name
- project_name
- stack_path
- compose_file
- desired_commit_sha
- update_policy
- backup_policy
- healthcheck_json
- rollback_json
- risk_level

compose_services
- id
- stack_id
- service_name
- image
- desired_digest
- actual_digest
- update_policy
- risk_level

image_update_candidates
- id
- service_id
- current_image
- current_digest
- remote_image
- remote_digest
- detected_at
- status
- risk_level

update_plans
- id
- candidate_id
- plan_json
- backup_plan_json
- healthcheck_plan_json
- rollback_plan_json
- status
- policy_status
- approved_by
- approved_at

update_runs
- id
- plan_id
- status
- stdout
- stderr
- raw_event_data
- backup_result_json
- healthcheck_result_json
- rollback_result_json
- started_at
- finished_at

也可以先复用现有 ResourceDiff / ApplyPlan / GitOpsApplyRun,等更新能力稳定后再拆专表。


前端页面规划

1. Compose Stacks

展示:

  • host
  • stack name
  • project name
  • stack path
  • desired commit
  • actual status
  • update policy
  • risk level
  • health status

2. Actual State Scanner

展示:

  • 最近扫描时间。
  • 扫描主机。
  • Docker / Compose 状态。
  • 扫描错误。
  • orphaned resources。

3. Compose Policy Results

展示:

  • stack / service。
  • 命中的策略。
  • severity。
  • passed / blocked。
  • 修复建议。

4. Image Updates

展示:

  • service。
  • current digest。
  • remote digest。
  • update policy。
  • risk level。
  • candidate status。

5. Update Plans

展示:

  • 计划步骤。
  • 备份策略。
  • 健康检查。
  • 回滚方案。
  • 审批按钮。

6. Update Runs / Audit Log

展示:

  • 更新历史。
  • 成功 / 失败。
  • 健康检查结果。
  • 回滚结果。
  • stdout / stderr。

与 AI-native GitOps Roadmap 的关系

本 issue 不是替代 issue #1,而是 issue #1 的工程落地延伸。

issue #1 关注:

Evidence Pack
AI Incident Analysis
GitOps Desired State
Diff / Plan
Policy Validation
AI Proposal
Operation Module Proposal Factory

本 issue 关注:

真实多主机 GitOps Compose Apply
Actual State Scanner
Compose Policy Engine
Image Update Detection
Update Plan
Backup / Healthcheck / Rollback / Audit

AI 在本 issue 中的合理角色:

  • 解释 PolicyResult。
  • 生成 Update Plan 的自然语言摘要。
  • 根据失败 Update Run 生成 Incident Report。
  • 根据多次更新失败沉淀 Runbook。
  • 生成 GitOps Change Proposal 或 Operation Module Proposal。

AI 不应该:

  • 自动决定更新高风险服务。
  • 绕过 policy validation。
  • 直接执行 shell。
  • 在没有 Evidence Pack / Update Run 证据的情况下自由猜测。

分版本实现路线

v1.1.0 — Real Multi-host GitOps Compose Apply

目标:把 v1.0.0 的 localhost demo apply 升级为真实多主机 Compose Apply。

范围:

  • 引入正式 YAML parser。
  • 定义 docs/desired-state-schema.md
  • 解析 hosts/*.yamlstacks/*/stack.yamlstacks/*/compose.yaml
  • Stack 支持 target_hoststack_pathcompose_file
  • Apply 使用 Host 表 / desired host 生成真实 Ansible inventory。
  • 远程创建 /opt/stacks/<stack>
  • 同步 compose.yaml。
  • 执行 docker compose configdocker compose pulldocker compose up -d
  • Apply Run 保存 host、stack path、commit SHA、stdout、stderr、raw events、rollback metadata。

验收:

  • Git 中声明一个 stack 指向 monitoring-01
  • Astralith 能在 monitoring-01 上部署该 stack。
  • 不再依赖 localhost inventory 完成主演示。

v1.2.0 — Actual State Scanner and Orphan Diff

目标:让平台能从目标主机自动扫描实际状态,并识别漂移。

范围:

  • 新增 Actual State Scanner。
  • 通过 Ansible Runner 执行只读 Docker / Compose 探测命令。
  • 自动写入 Actual Resources。
  • 生成 create / update / orphaned / delete_candidate diff。
  • UI 展示扫描结果和 orphaned resources。
  • 默认不自动删除 orphan,只生成 warning / review plan。

验收:

  • 用户点击 Scan Actual State 后,平台能展示目标主机上的 stack / container / image 状态。
  • Git 删除 stack 后,平台能识别目标主机仍存在的 orphaned stack。

v1.3.0 — Compose Policy Engine

目标:把策略校验从演示规则升级为真实 Compose 风险检查。

范围:

  • 解析 compose.yaml services / volumes / ports / labels。
  • 检测 privileged、host network、docker.sock、危险挂载、latest、公开端口、缺少 restart、数据库无 volume 等风险。
  • 生成 PolicyResult。
  • 高危规则阻断 Apply / Update Plan。
  • 中低危规则提示人工审核。
  • 前端新增 Compose Policy Results 展示。

验收:

  • privileged: true 或 docker.sock 挂载的 compose 会被高危标记。
  • 使用 latest 的服务会被提示或阻断,具体取决于 update policy / risk level。
  • PolicyResult 能清楚解释命中原因。

v1.4.0 — Image Update Detection MVP

目标:实现只检测、不执行的容器镜像更新能力。

范围:

  • 从 compose.yaml 读取 image。
  • 从 actual scan 读取当前运行 digest。
  • 查询远端 registry digest。
  • 生成 Image Update Candidate。
  • 根据 label / stack metadata 显示 auto / notify / manual / frozen。
  • UI 展示更新候选。
  • 不执行更新。

验收:

  • 平台能显示某个 service 当前 digest 与远端 digest 是否一致。
  • 有更新时生成 candidate。
  • latest / floating tag 被明确提示风险。

v1.5.0 — Human-approved Update Plan

目标:让平台能生成人工审批的容器更新计划。

范围:

  • 基于 Image Update Candidate 生成 Update Plan。
  • 包含备份计划、健康检查计划、回滚计划。
  • 人工 approve / reject。
  • 只允许 notify / manual 服务在审批后执行。
  • 执行 docker compose pulldocker compose up -d
  • 记录 Update Run。

验收:

  • 用户可以从 UI 查看更新计划并批准。
  • 更新执行后保存 stdout / stderr / raw events。
  • 失败时不静默吞掉错误。

v1.6.0 — Backup, Healthcheck and Rollback

目标:让更新编排具备安全闭环。

范围:

  • 支持 backup_policy
  • 更新前备份配置目录或 SQLite 数据。
  • 更新后执行容器状态、Docker healthcheck、端口、HTTP 检查。
  • 健康检查失败时触发 rollback plan。
  • 保存 backup / healthcheck / rollback 结果。

验收:

  • 更新前能生成并执行备份。
  • 健康检查失败时能回滚或至少生成明确回滚任务。
  • Update Run 记录完整审计信息。

v1.7.0 — Limited Automatic Updates

目标:在安全闭环完整后,允许低风险服务有限自动更新。

范围:

  • 只允许 dev.nesoriel.update.policy=auto 且 risk low 的服务进入自动更新。
  • 必须有 healthcheck。
  • 必须有 rollback strategy。
  • 必须有最近成功备份或无需备份证明。
  • 自动更新必须写入审计日志。
  • 提供全局开关禁用自动更新。

验收:

  • low-risk auto 服务可自动更新。
  • high-risk / manual / frozen 服务不能自动更新。
  • 任意自动更新失败都能生成 Evidence Pack 和 Incident Report。

非目标

暂时不做:

  • 无脑替代 Watchtower。
  • 无人值守更新所有容器。
  • 直接自动更新入口层、数据库、对象存储、下载器、管理面板自身。
  • 将真实 .env、密钥或原始私钥提交到公开仓库。
  • 绑定某一个特定更新器实现。
  • 直接做完整 Docker 平台或镜像构建平台。
  • 直接做 Kubernetes / Argo CD 替代品。
  • 在没有多主机 GitOps Apply 的情况下提前做自动更新。

毕设与长期价值

这个路线可以让 Astralith 区别于普通面板、Watchtower 类自动更新器或简单脚本:

  • 不是简单包装 Docker Compose。
  • 不是依赖失去维护的自动更新器。
  • 不是让 AI 直接操作服务器。
  • 而是围绕 GitOps、Ansible Runner、Compose Policy、人工审批、备份、健康检查、回滚和审计,形成安全可控的更新编排能力。

对毕业设计来说,它可以作为 v1.0.0 之后的后续工作与展望;对个人 homelab 来说,它可以成为 Astralith 真正开始管理多台服务器的关键路线。

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions