Two Forgejo runbooks plus the Authentik OAuth2 provider guide, mirrored from the iCloud folder into the versioned repo. Runbooks: - forgejo-admin-recovery.md — fallback login when Authentik is down using the local admin-local user (prohibit_login reset via SQL). - forgejo-backup-restore.md — backup format, restore scenarios (full / DB-only / single file), disaster recovery on new host. Guides: - authentik-oauth2-provider.md — reusable template for adding native OIDC integrations in Authentik. First applied for Forgejo, ready to reuse for OpenProject, Nextcloud, Grafana. Includes the important launch-URL gotcha from ADR-0006. Each category folder has a README.md with format conventions and an index of the current documents. Refs OP#1118
138 lines
4.1 KiB
Markdown
138 lines
4.1 KiB
Markdown
# Runbook — Forgejo Backup und Restore
|
|
|
|
## Backup-Architektur
|
|
- **Script:** `/opt/ai-apps/forgejo/backup.sh`
|
|
- **Cron:** `0 3 * * *` (täglich 03:00 UTC auf ai-apps)
|
|
- **Ziel:** `/opt/backups/forgejo/`
|
|
- **Format:**
|
|
- `forgejo-db-<YYYYMMDD-HHMMSS>.sql.gz` — pg_dump der Postgres DB
|
|
- `forgejo-data-<YYYYMMDD-HHMMSS>.tar.gz` — tar des Forgejo `/data` Volumes
|
|
- **Retention:** 14 Tage (ältere Dateien werden via `find -mtime +14 -delete` entfernt)
|
|
|
|
## Manueller Backup-Run
|
|
```bash
|
|
ssh ai-apps
|
|
bash /opt/ai-apps/forgejo/backup.sh
|
|
ls -lh /opt/backups/forgejo/
|
|
```
|
|
|
|
Erwartete Ausgabe:
|
|
```
|
|
[2026-04-11T19:39:11+00:00] backup start
|
|
db dump: 26K
|
|
data tar: 12K
|
|
[2026-04-11T19:39:12+00:00] backup complete
|
|
```
|
|
|
|
## Restore-Szenarien
|
|
|
|
### Szenario A: Komplett-Restore aus Backup (Disaster Recovery)
|
|
|
|
Voraussetzung: Backup-Files sind vorhanden (entweder in `/opt/backups/forgejo/` oder aus Offsite-Kopie).
|
|
|
|
```bash
|
|
# 1. Stack stoppen
|
|
cd /opt/ai-apps/forgejo
|
|
docker compose down
|
|
|
|
# 2. Volumes löschen (ACHTUNG: unwiderruflich!)
|
|
docker volume rm forgejo_forgejo-data forgejo_forgejo-db-data
|
|
|
|
# 3. Stack wieder starten — leere Volumes werden neu angelegt
|
|
docker compose up -d forgejo-db
|
|
|
|
# 4. Warten bis Postgres healthy
|
|
sleep 20
|
|
docker ps --filter name=forgejo-db --format '{{.Status}}' # Up (healthy)
|
|
|
|
# 5. DB restoren
|
|
gunzip -c /opt/backups/forgejo/forgejo-db-<TIMESTAMP>.sql.gz | \
|
|
docker exec -i forgejo-db psql -U forgejo -d forgejo
|
|
|
|
# 6. Data volume restoren
|
|
docker run --rm \
|
|
-v forgejo_forgejo-data:/data \
|
|
-v /opt/backups/forgejo:/backup:ro \
|
|
alpine \
|
|
sh -c "cd /data && tar -xzf /backup/forgejo-data-<TIMESTAMP>.tar.gz"
|
|
|
|
# 7. Forgejo starten
|
|
docker compose up -d forgejo
|
|
|
|
# 8. Verifikation
|
|
sleep 30
|
|
curl -s https://code.sdda.eu/api/healthz
|
|
curl -s https://code.sdda.eu/api/v1/version
|
|
docker exec -u git forgejo sh -c 'cd / && forgejo admin user list'
|
|
```
|
|
|
|
### Szenario B: Nur DB zurückspielen (z.B. nach Korruption durch Update)
|
|
|
|
```bash
|
|
cd /opt/ai-apps/forgejo
|
|
docker compose stop forgejo # nur Forgejo, nicht DB
|
|
|
|
# DB mit -c wipen und neu importieren
|
|
docker exec forgejo-db psql -U forgejo -d postgres \
|
|
-c "DROP DATABASE forgejo;"
|
|
docker exec forgejo-db psql -U forgejo -d postgres \
|
|
-c "CREATE DATABASE forgejo OWNER forgejo;"
|
|
|
|
gunzip -c /opt/backups/forgejo/forgejo-db-<TIMESTAMP>.sql.gz | \
|
|
docker exec -i forgejo-db psql -U forgejo -d forgejo
|
|
|
|
docker compose start forgejo
|
|
```
|
|
|
|
### Szenario C: Einzelne Datei / Config aus Data-Volume wiederherstellen
|
|
|
|
```bash
|
|
# Tar-Inhalt inspizieren
|
|
tar -tzf /opt/backups/forgejo/forgejo-data-<TIMESTAMP>.tar.gz | head -30
|
|
|
|
# Einzelne Datei extrahieren
|
|
mkdir -p /tmp/forgejo-restore
|
|
tar -xzf /opt/backups/forgejo/forgejo-data-<TIMESTAMP>.tar.gz \
|
|
-C /tmp/forgejo-restore gitea/conf/app.ini
|
|
|
|
# Ins laufende Volume kopieren
|
|
docker cp /tmp/forgejo-restore/gitea/conf/app.ini forgejo:/data/gitea/conf/app.ini
|
|
docker restart forgejo
|
|
```
|
|
|
|
## Disaster-Recovery: Kompletter Neuaufbau auf neuem Server
|
|
|
|
1. Neuen Host aufsetzen (Docker + Compose)
|
|
2. `/opt/ai-apps/forgejo/` Stack-Verzeichnis kopieren (inkl. `.env`, docker-compose.yml, backup.sh)
|
|
3. Backup-Files aus Offsite-Quelle holen (Nextcloud / Hetzner Snapshot)
|
|
4. Szenario A durchführen
|
|
5. DNS ggf. auf neue IP anpassen
|
|
|
|
## Verification nach Restore
|
|
```bash
|
|
# Health
|
|
curl -s https://code.sdda.eu/api/healthz
|
|
|
|
# Auth-Sources
|
|
docker exec -u git forgejo sh -c 'cd / && forgejo admin auth list'
|
|
# Erwartet: 1 authentik OAuth2 true
|
|
|
|
# User
|
|
docker exec -u git forgejo sh -c 'cd / && forgejo admin user list'
|
|
# Erwartet: admin-local + bw + alle anderen
|
|
|
|
# Repo-Zähler
|
|
docker exec forgejo-db psql -U forgejo -d forgejo \
|
|
-c "SELECT count(*) FROM repository;"
|
|
```
|
|
|
|
## Offsite-Backup-Strategie (zukünftig, M7.5)
|
|
- **Tier 2:** rclone → Nextcloud, zweiter Cron 03:30
|
|
- **Tier 3:** Hetzner Cloud Snapshot, manuell wöchentlich
|
|
|
|
Beides noch nicht eingerichtet — solange lokale 14-Tage-Retention + Hetzner-VM-Stabilität unser Sicherheitsnetz.
|
|
|
|
## Was NIE machen
|
|
- Backup-Files niemals in Git einchecken (können sensible Repo-Daten enthalten)
|
|
- Restore auf laufender Prod ohne vorheriges Backup (einfach `docker compose down` macht keine DB-Kopie!)
|
|
- `docker volume prune` wenn Forgejo noch läuft (wird Daten verlieren)
|