Add Forgejo daily backup automation (T04/T09 Option A)
make forgejo-backup runs forgejo dump + pg_dump, age-encrypts, uploads to Nextcloud forgejo/ prefix. Includes dry-run, status, and operator docs.
This commit is contained in:
parent
0055e8f3f7
commit
074e7f8441
3 changed files with 25 additions and 10 deletions
|
|
@ -22,6 +22,10 @@ make forgejo-backup-status # last success + 7-day gate hint
|
||||||
|
|
||||||
Requires: `kubectl`, `age`, `curl`, `KUBECONFIG=~/.kube/config-hosteurope`.
|
Requires: `kubectl`, `age`, `curl`, `KUBECONFIG=~/.kube/config-hosteurope`.
|
||||||
|
|
||||||
|
Preflight: `forgejo-db` pod must be Ready (`make forgejo-db-status`). A full dump
|
||||||
|
with 13 org repos is ~670MiB — allow 10–20 minutes for stream + age on a typical
|
||||||
|
workstation link.
|
||||||
|
|
||||||
Decrypt: `~/.config/age/railiance-backup.key` (same key as other Railiance backups).
|
Decrypt: `~/.config/age/railiance-backup.key` (same key as other Railiance backups).
|
||||||
|
|
||||||
## Nextcloud layout
|
## Nextcloud layout
|
||||||
|
|
|
||||||
8
lib/railiance-print.sh
Normal file
8
lib/railiance-print.sh
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# lib/railiance-print.sh — shared pretty printers for platform operator tools
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
print_hdr() { printf "\n%s\n" "$1"; printf "%0.s-" $(seq 1 "${#1}"); echo; }
|
||||||
|
ok() { printf " ✅ %-12s %s\n" "$1" "$2"; }
|
||||||
|
warn() { printf " ⚠️ %-12s %s\n" "$1" "$2"; }
|
||||||
|
bad() { printf " ❌ %-12s %s\n" "$1" "$2"; }
|
||||||
|
|
@ -51,6 +51,12 @@ if [[ -z "${FORGEJO_DB_POD}" ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! kubectl wait --for=condition=Ready "pod/${FORGEJO_DB_POD}" \
|
||||||
|
-n "${FORGEJO_DB_NAMESPACE}" --timeout=180s >/dev/null 2>&1; then
|
||||||
|
bad "preflight" "forgejo-db pod not Ready (check: make forgejo-db-status)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
PROD_POD="$(kubectl get pods -n "${FORGEJO_NAMESPACE}" \
|
PROD_POD="$(kubectl get pods -n "${FORGEJO_NAMESPACE}" \
|
||||||
-l "app.kubernetes.io/instance=${FORGEJO_RELEASE}" \
|
-l "app.kubernetes.io/instance=${FORGEJO_RELEASE}" \
|
||||||
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)"
|
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)"
|
||||||
|
|
@ -68,20 +74,17 @@ ok "forgejo-db" "${FORGEJO_DB_NAMESPACE}/${FORGEJO_DB_POD}"
|
||||||
# 1. Application dump (repos, packages, attachments, LFS, avatars)
|
# 1. Application dump (repos, packages, attachments, LFS, avatars)
|
||||||
ok "forgejo dump" "running in pod…"
|
ok "forgejo dump" "running in pod…"
|
||||||
DUMP_REMOTE="/tmp/forgejo-backup-${TS}.zip"
|
DUMP_REMOTE="/tmp/forgejo-backup-${TS}.zip"
|
||||||
|
# Single exec: dump then stream stdout (avoids kubectl cp / multi-exec websocket drops)
|
||||||
kubectl exec -n "${FORGEJO_NAMESPACE}" "${PROD_POD}" -c gitea -- \
|
kubectl exec -n "${FORGEJO_NAMESPACE}" "${PROD_POD}" -c gitea -- \
|
||||||
forgejo dump -f "${DUMP_REMOTE}"
|
sh -c "forgejo dump -f '${DUMP_REMOTE}' && cat '${DUMP_REMOTE}' && rm -f '${DUMP_REMOTE}'" \
|
||||||
# cat stream avoids kubectl cp websocket drops on larger archives
|
> "${DUMP_PLAIN}"
|
||||||
kubectl exec -n "${FORGEJO_NAMESPACE}" "${PROD_POD}" -c gitea -- \
|
ok "forgejo dump" "$(du -h "${DUMP_PLAIN}" | awk '{print $1}') $(basename "${DUMP_PLAIN}")"
|
||||||
cat "${DUMP_REMOTE}" > "${DUMP_PLAIN}"
|
|
||||||
kubectl exec -n "${FORGEJO_NAMESPACE}" "${PROD_POD}" -c gitea -- \
|
|
||||||
rm -f "${DUMP_REMOTE}"
|
|
||||||
ok "forgejo dump" "$(du -h "${DUMP_PLAIN}" | awk '{print $1}') → $(basename "${DUMP_PLAIN}")"
|
|
||||||
|
|
||||||
# 2. PostgreSQL logical dump (stdout; CNPG data dir is read-only for ad-hoc paths)
|
# 2. PostgreSQL logical dump (plain SQL to stdout; CNPG root FS is read-only)
|
||||||
ok "pg_dump" "database forgejo…"
|
ok "pg_dump" "database forgejo…"
|
||||||
kubectl exec -n "${FORGEJO_DB_NAMESPACE}" "${FORGEJO_DB_POD}" -c postgres -- \
|
kubectl exec -n "${FORGEJO_DB_NAMESPACE}" "${FORGEJO_DB_POD}" -c postgres -- \
|
||||||
pg_dump -U postgres -d forgejo -Fc --no-owner --no-acl -f - > "${DB_PLAIN}"
|
pg_dump -U postgres -d forgejo --no-owner --no-acl > "${DB_PLAIN}"
|
||||||
ok "pg_dump" "$(du -h "${DB_PLAIN}" | awk '{print $1}') → $(basename "${DB_PLAIN}")"
|
ok "pg_dump" "$(du -h "${DB_PLAIN}" | awk '{print $1}') $(basename "${DB_PLAIN}")"
|
||||||
|
|
||||||
# 3. Encrypt
|
# 3. Encrypt
|
||||||
railiance_backup_encrypt "${DUMP_PLAIN}" "${DUMP_AGE}"
|
railiance_backup_encrypt "${DUMP_PLAIN}" "${DUMP_AGE}"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue