Add /docs/infra/config-to-git.md listing all 4 repos, schedules, script paths, and HAOS-specific addon init_commands pattern. RESUME updated to reflect HAOS bootstrap done 2026-05-24.
4.1 KiB
Config-to-git fleet
Each host snapshots its critical config to a private Gitea repo on git.nuclide.systems daily. Force-push (mirror only — history isn't sacred). Token: long-lived fkrebs PAT embedded in remote URLs (mode 0600 on script/config).
Repos
| Host | CT/VM | Repo | Schedule | Script | Source |
|---|---|---|---|---|---|
PVE (nuc) |
host | fkrebs/pve-conf | daily 03:00 | /usr/local/sbin/pve-conf-backup.sh (cron /etc/cron.d/pve-conf-backup) |
/etc/pve/ (excludes priv/, *.key, authkey.pub*) |
| Zoraxy | CT 108 | fkrebs/zoraxy-conf | daily 03:00 | /usr/local/sbin/zoraxy-conf-backup.sh (cron /etc/cron.d/zoraxy-conf-backup) |
Zoraxy config dir |
| AdGuard | CT 102 | fkrebs/adguard-conf | daily 03:00 | /usr/local/sbin/adguard-conf-backup.sh (cron /etc/cron.d/adguard-conf-backup) |
AdGuard config dir |
| Home Assistant | VM 100 | fkrebs/home-assistant-config | manual cron via addon init_commands (see below) |
/config/scripts/git-push.sh |
/config/ (sees .gitignore allowlist) |
fkrebs/ha-config was created in error 2026-05-24 — unused, can be deleted.
Pattern
All scripts follow the same shape:
#!/bin/bash
set -e
REPO_URL="https://fkrebs:<TOKEN>@git.nuclide.systems/fkrebs/<repo>.git"
WORK="/tmp/<name>-work"
mkdir -p "$WORK"
git -C "$WORK" init -b main -q 2>/dev/null || true
git -C "$WORK" config user.email "noreply@nuclide.systems"
git -C "$WORK" config user.name "<name>-backup"
git -C "$WORK" remote set-url origin "$REPO_URL" 2>/dev/null \
|| git -C "$WORK" remote add origin "$REPO_URL"
rsync -a --delete --exclude='.git' [+ secret excludes] <source>/ "$WORK/"
git -C "$WORK" add -A
git -C "$WORK" commit -q -m "auto: $(date -u +%Y-%m-%dT%H:%M:%SZ)" 2>/dev/null || true
git -C "$WORK" push -q --force origin main
PVE/CT 108/CT 102 use a rsync-to-tmp-then-push pattern. HAOS uses an in-place git add -A on /config because the .gitignore there is hand-curated with an allowlist for .storage/.
HAOS specifics
-
Path:
/config/scripts/git-push.sh(mode 0700, runs in the Terminal & SSH addon). -
Remote:
https://fkrebs:<TOKEN>@git.nuclide.systems/fkrebs/home-assistant-config.git. Token lives in/config/.git/config(mode 0600). -
.gitignoreuses a default-deny allowlist for.storage/— only safe registry/lovelace/helpers/energy files are tracked. Tokens (core.config_entries,mobile_app,androidtv_adbkey*, etc.) are explicitly excluded. See/config/.gitignoreon HAOS for the full list. -
Scheduling — Terminal & SSH addon container is rebuilt on update, so its
crontabs/are not persistent. Use the addon'sinit_commands(Configuration tab):init_commands: - 'echo "0 3 * * * /config/scripts/git-push.sh >> /config/scripts/git-push.log 2>&1" > /etc/crontabs/root && crond -b'Then Restart the addon. Alternative: HA automation calling
shell_commandis not viable — thehomeassistantcontainer doesn't have SSH to addon containers.
Token rotation
All four repos use the same PAT (fkrebs user, full repo scope). Rotate by:
- Generate new PAT in Gitea → user settings → applications.
git remote set-url origin https://fkrebs:<NEW>@git.nuclide.systems/fkrebs/<repo>.giton each host.- Manually run each script once to verify.
Token leak risk: tracked in gitea_open_issues; long-term move is to switch to per-host deploy keys.
Verification
Last commit on each repo should be auto: <today>T03:0X:XXZ. Quick check:
for r in pve-conf zoraxy-conf adguard-conf home-assistant-config; do
echo -n "$r: "
curl -sk -H "Authorization: token <TOKEN>" \
"https://git.nuclide.systems/api/v1/repos/fkrebs/$r/commits?limit=1" \
| python3 -c 'import json,sys; c=json.load(sys.stdin)[0]; print(c["commit"]["author"]["date"], c["commit"]["message"][:60])'
done
Related
- homelab-architecture — host topology
- backrest-ct103 — separate, repo-style binary backup for data (not config)