* Add encrypted Gitea offsite backups * Avoid Homebrew cleanup in Gitea backup * Use dedicated Spaces credentials for Gitea backups * Authenticate Gitea backups with a dedicated SSH key * Use SCP for Synology Gitea backups * Skip regenerable unreadable Gitea state * Finalize scheduled Gitea backup workflow * Group Gitea backup retention across runners
3.2 KiB
Gitea offsite backups
Eagle0's Gitea mirror keeps Git and Git LFS data on zog for fast local
access. The Gitea Offsite Backup GitHub Actions workflow copies the
recoverable state to an encrypted Restic repository in the private
eagle0-gitea-backups DigitalOcean Space.
Backup contents
Each snapshot contains:
- a transactionally consistent SQLite backup of the Gitea database;
- Gitea configuration and persistent application data;
- every locally stored Git LFS object;
- a fresh mirror clone of
admin/eagle0; - the Gitea version and captured
maincommit inmanifest.txt.
Regenerable indexes, sessions, queues, repository archives, logs, and the OAuth2 JWT signing key are excluded. Gitea creates a new JWT signing key when none exists, which invalidates pre-restoration OAuth2 tokens. Container-managed SSH host keys are not readable by the backup account and must also be regenerated after a complete NAS loss.
Schedule and retention
The backup runs daily at 10:23 UTC on a halfdan self-hosted runner. Each
run validates the SQLite snapshot, runs git fsck, uploads an encrypted
snapshot, and reads a rotating 5% sample of the Restic repository.
Weekly maintenance runs Sunday at 11:53 UTC. It retains 14 daily, 8 weekly, 12 monthly, and 3 yearly snapshots, prunes unreferenced Restic packs, and reads a rotating 10% sample.
Use the workflow's full_restore_verify option after storage or credential
changes. It downloads the latest snapshot, validates the restored SQLite
database, and runs git fsck against the restored repository.
Credentials
GitHub Actions stores:
GITEA_DO_SPACES_ACCESS_KEYGITEA_DO_SPACES_SECRET_KEYDO_SPACES_ENDPOINTGITEA_BACKUP_SSH_KEYGITEA_RESTIC_PASSWORD
GITEA_BACKUP_SSH_KEY is a dedicated key accepted by the NAS account used for
backup reads. It is not a copy of a developer's personal SSH key.
The Restic recovery password also has an offline recovery copy in the
workstation's macOS Keychain under service eagle0-gitea-restic. Never put
that password in the repository, workflow logs, or a support ticket.
Restore
Install restic, then set the DigitalOcean credentials, Restic repository,
and Restic password in the shell performing the restore. Restore into an
empty directory:
restic snapshots --host zog --tag gitea
restic restore latest --host zog --tag gitea --target /path/to/restore
The snapshot preserves the absolute staging path below the restore target.
Locate manifest.txt; its containing directory is the restored backup root.
Before changing Gitea:
sqlite3 /path/to/restored/root/gitea/gitea.db "PRAGMA integrity_check;"
git --git-dir=/path/to/restored/root/repositories/admin/eagle0.git fsck --full
To recover a complete installation:
- Recreate the same Gitea version shown in
manifest.txt. - Stop Gitea.
- Restore
config,gitea,lfs, and the bare repository into the matching paths under/volume2/docker/gitea. - Preserve the restored file ownership expected by the container.
- Allow Gitea to regenerate indexes, sessions, queues, archives, and SSH host keys.
- Start Gitea and verify a historical LFS checkout before enabling writes.
Do not overwrite a running installation during a restore.