feat: add gated Compose deploy and make inventory the host source of truth

Keep sanitized Compose sources in-repo with a confirmation-gated Ansible
playbook, add repo-wide validation, tighten runbook ownership/STOP/review
metadata, and archive stale research docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
windyboy
2026-08-17 17:36:39 +08:00
co-authored by Cursor
parent 885d977531
commit 343c5db415
35 changed files with 912 additions and 276 deletions
+6
View File
@@ -9,6 +9,12 @@ Read-only health check of the AdGuard Home LAN DNS service.
- Applicable: [dns.windy.lan](../hosts/dns.windy.lan.md) (`192.168.66.36`).
- Read-only: does not expose query-log contents or secrets; does not change configuration.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: dns.windy.lan (`/opt/adguardhome`)
This runbook is read-only. It does not expose query-log contents or secrets.
Routine checks run through Ansible on demand:
+27
View File
@@ -18,6 +18,12 @@ account with sudo. Do a read-only health pass before any reconciliation.
- Mutating playbooks require explicit confirmation variables; do not bypass them.
- If a reconcile target or service name is not allowlisted, `STOP` — do not invent one.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: Ansible control-plane + all inventory hosts
## Health report (read-only)
```bash
@@ -63,6 +69,27 @@ Do not use this playbook for a Mailcow update, database migration, DNS record
change, or secret rotation. Those operations require their dedicated reviewed
and, where appropriate, interactive procedures.
## Deploy repo-owned Compose (static projects)
Repo source: `compose/<project>/compose.yml` (non-secret; secrets come from the
server-local `.env` via `${VAR}`). Mechanism and per-project status:
[`compose/README.md`](../compose/README.md).
```bash
# Read-only: staged-file diff + allowlist/confirmation asserts, no writes
ansible-playbook playbooks/compose-deploy.yml --limit vaultwarden --check --diff
ansible-playbook playbooks/compose-deploy.yml --limit powerdns --check --diff
# Apply: stage repo file → validate `docker compose config -q` against the
# server .env → backup current file (*.bak-<ts>) → promote → `up -d` (gated)
ansible-playbook playbooks/compose-deploy.yml --limit vaultwarden \
-e '{"compose_deploy_confirm": true}'
```
The playbook never writes, reads, or transfers the server `.env`. A failed
validation never touches the live compose file. Hosts without an allowlisted
`compose_repo_project` fail the assert — do not invent targets.
## Host-level maintenance
These playbooks cover every inventory host, including the Matrix K3s node:
+6
View File
@@ -20,6 +20,12 @@ skipping checks or changing unrelated code.
- Do not change unrelated hosts or services.
- Prefer read-only diagnosis before mutation; destructive fixes require approval.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: Ansible health report / gated playbooks
## Procedure
### Step 1 — Reproduce and read
+8
View File
@@ -21,6 +21,12 @@ read-only checks and gated mutating operations; the "Command families
intentionally NOT scripted" table below lists what is deliberately out of
scope.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: hass.windy.lan (HAOS, `machine: green`)
## Safety
- Prefer read-only checks first; the health snapshot mutates nothing.
@@ -33,6 +39,8 @@ scope.
state via Supervisor (`SUPERVISOR_TOKEN` after `sudo -n -i`).
- The `--restart-core` wrapper exits 1 silently on ssh failure — treat an
empty/exit-1 result as failure and confirm with `ha core info`.
- If live state conflicts with a documented expectation, `STOP` and report;
do not improvise command families outside this script.
## Access pattern
+6 -2
View File
@@ -51,9 +51,13 @@ and ask for clarification (add a `needs-info` label if applicable). Otherwise go
### Step 3 — Verify
**Action** — run the applicable verification (link check for docs; `ansible-playbook --check` / `--syntax-check` for playbooks).
**Action** — run `scripts/validate-repo.sh` from the repo root (covers secret
scan, inventory cross-check, markdown link check, runbook-spec check, and
Ansible `--syntax-check`); for changes that alter playbook behavior, also run
a read-only `ansible-playbook --check` where possible.
**Verification**see `RUNBOOKS.md` §校验; the concrete checks must match the change type.
**Verification**`scripts/validate-repo.sh` exits 0; see `RUNBOOKS.md`
§校验; the concrete checks must match the change type.
**Decision** — verification passed → Step 4; failed → Troubleshooting A.
+6
View File
@@ -9,6 +9,12 @@ Read-only health check of the mailcow stack on mx2.
- Applicable: [mx2.windy.me](../hosts/mx2.windy.me.md), `/opt/mail`.
- Read-only: does not change mailcow configuration or service state.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: mx2.windy.me (`/opt/mail`)
Target: [mx2.windy.me](../hosts/mx2.windy.me.md)
Path: `/opt/mail`
Prefer: the Ansible health report (`ansible/playbooks/health-report.yml --limit mailcow`),
+7
View File
@@ -9,6 +9,12 @@ Reference for configuring mail clients against the mailcow SMTP/IMAP endpoints.
- Applicable: [mx2.windy.me](../hosts/mx2.windy.me.md) client submission (587/465) and IMAP/POP (993/995).
- Not applicable: server-side mailcow configuration or administration.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: mx2.windy.me (SMTP/IMAP client endpoints)
Target: [mx2.windy.me](../hosts/mx2.windy.me.md)
Prerequisite: a mailbox on `windy.me` (password from mailcow UI, not the admin account unless it is that mailbox).
@@ -66,3 +72,4 @@ Do not commit or paste real passwords into this repo.
- Do not commit or paste real passwords into this repo or chat.
- Use submission (587/465) for client sending; never use port 25 as a desktop/app outbound port.
- If live state conflicts with the endpoint values above, `STOP` and report; do not change server-side settings during this reference check.
+7
View File
@@ -9,6 +9,12 @@ Update the mailcow stack on mx2 to the latest supported release.
- Applicable: [mx2.windy.me](../hosts/mx2.windy.me.md), `/opt/mail`.
- Not applicable: config changes beyond the update, DB migration, secret rotation.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: mx2.windy.me (`/opt/mail`)
## Approval gates
| Action | Risk | Explicit approval |
@@ -24,6 +30,7 @@ Path: `/opt/mail`
- Never run the update without explicit user confirmation.
- Never pass secrets into the chat log; do not commit `mailcow.conf`.
- If a step fails, capture `docker compose ps` and logs and stop before further changes.
- If live state conflicts with this runbook's assumptions (e.g. unexpected `mailcow.conf` values), `STOP` and report.
## Before
+6
View File
@@ -9,6 +9,12 @@ Read-only health check of the Matrix homeserver (ESS on K3s).
- Applicable: [synapse.chans.xyz](../hosts/synapse.chans.xyz.md), namespace `ess`.
- Read-only: does not change pods, ingress, certificates, or configuration.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: synapse.chans.xyz (ESS chart `26.7.2`, K3s)
Monitor the Matrix homeserver running on `synapse.chans.xyz` (ESS chart `26.7.2`, K3s node).
Prefer `cd ansible && ansible-playbook playbooks/health-report.yml --limit matrix`
+6
View File
@@ -10,6 +10,12 @@ gateway, VLAN) with impact assessment, approval, and a rollback path.
- Applicable: PowerDNS zone records, `us4` firewalld allowlist, LAN gateway/VLAN/DNS changes, WireGuard.
- Not applicable: SSH access-policy changes (see `AGENTS.md` §SSH access safety — mandatory lockout-risk procedure).
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: PowerDNS / us4 firewalld / LAN gateway / WireGuard
## Preconditions
- A change record (Linear `vps` issue) describes the change, its reason, and rollback.
+6
View File
@@ -10,6 +10,12 @@ diagnosis and mutating only when the root cause is confirmed.
- Applicable: unreachable VPS services, LAN gateway/DNS failures, DNS resolution failures.
- Not applicable: planned changes (→ `network-change.md`), SSH access recovery (→ `AGENTS.md` §SSH access safety).
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: VPS services / LAN gateway / DNS
## Safety
- Read-only diagnosis first; do not mutate while the root cause is unknown.
+6
View File
@@ -9,6 +9,12 @@ Read-only health check of the `/opt/pdns` PowerDNS stack.
- Applicable: [hk2.chans.xyz](../hosts/hk2.chans.xyz.md), `/opt/pdns`.
- Read-only: does not change PowerDNS, DNS records, or secrets.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: hk2.chans.xyz (`/opt/pdns`)
Read-only checks for the `/opt/pdns` stack on **hk2.chans.xyz** (`ns1.wsvc.info`).
Facts: [hosts/hk2.chans.xyz.md](../hosts/hk2.chans.xyz.md) · Upstream: [docs/pdns-upstream.md](../docs/pdns-upstream.md)
+6
View File
@@ -10,6 +10,12 @@ verifiable, rollback-safe way.
- Applicable: reviewed changes to Compose services, DNS, firewall, or Ansible-managed config on production hosts.
- Not applicable: destructive migrations (`vaultwarden-sqlite-to-postgres.md`), SSH access-policy changes (`AGENTS.md` §SSH access safety), or network changes needing a change ticket (`network-change.md`).
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: all production hosts
## Preconditions
- The change is reviewed and its intent matches a Linear issue / change record.
+6
View File
@@ -10,6 +10,12 @@ regression.
- Applicable: Compose services, DNS records, firewall rules, and Ansible-managed config that have a rollback point.
- Not applicable: destructive migrations without a backup (route to the owning runbook, e.g. `vaultwarden-sqlite-to-postgres.md` §Rollback).
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: all production hosts
## Preconditions
- A rollback point exists: backup, prior config, or known-good commit/playbook state.
+6
View File
@@ -9,6 +9,12 @@ Read-only health check of the `/opt/rustdesk` server stack.
- Applicable: [hk2.chans.xyz](../hosts/hk2.chans.xyz.md), `/opt/rustdesk`.
- Read-only: does not change RustDesk configuration or service state.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: hk2.chans.xyz (`/opt/rustdesk`)
Read-only checks for the `/opt/rustdesk` stack on **hk2.chans.xyz**.
Facts: [hosts/hk2.chans.xyz.md](../hosts/hk2.chans.xyz.md)
+6
View File
@@ -9,6 +9,12 @@ Read-only health check of the Vaultwarden stack (Postgres backend) on us2.
- Applicable: [us2.wsvc.info](../hosts/us2.wsvc.info.md), `/opt/vaultwarden`.
- Read-only: does not change Vaultwarden, Traefik, SMTP, or secrets.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: us2.wsvc.info (`/opt/vaultwarden`)
Target: [us2.wsvc.info](../hosts/us2.wsvc.info.md)
Path: `/opt/vaultwarden`
URL: https://auth.wsvc.info/
@@ -9,6 +9,12 @@ Replay checklist for the exceptional SQLite→Postgres migration on us2.
- Applicable: [us2.wsvc.info](../hosts/us2.wsvc.info.md), `/opt/vaultwarden`.
- Not applicable: routine reconcile — this is destructive and intentionally not automated.
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-17
- Related systems: us2.wsvc.info (`/opt/vaultwarden`)
## Safety
- Destructive: requires explicit approval; confirm backups exist before starting.