Gitea-Server sichern und wiederherstellen

Backup und Restore von Gitea: Der richtige Weg

Inhaltsverzeichnis

Gitea-Backups betreffen drei dynamische Komponenten – Datenbank, Git-Repositories und App-Dateien – und seit 2024 übernimmt der integrierte gitea dump-Befehl die gesamte Sicherung auf einen Schlag.

sehr gutes Foto einer geöffneten HDD

Im Beitrag Gitea testen haben wir den Gitea-Server installiert. Dies ist die Fortsetzung: Wie man ihn tatsächlich sichert und, was noch wichtiger ist, wiederherstellt, wenn etwas schiefgeht.

Für die vollständige Sammlung an Entwickler-Werkzeugen, einschließlich Git-Workflows und Docker-Verwaltung, siehe Entwickler-Werkzeuge: Der vollständige Leitfaden für moderne Entwicklungs-Workflows.

Wenn Sie Gitea zum ersten einrichten, werfen Sie einen Blick auf Kostenloser On-Premise-Git-Server wählen - Gitea ist der Gewinner! für Installationsdetails und auf Gitea SSL mit Apache als Reverse Proxy für die sichere Bereitstellung.

Wann man das üben sollte

Jetzt, einfach als Vorsichtsmaßnahme gegen böse Überraschungen, ist ein guter Zeitpunkt, um den Backup- und Restore-Prozess zu üben – bevor Sie ihn wirklich brauchen, nicht erst nach einem Festplattenausfall.

Lieber sicher als leid.

Wo die Daten liegen

Eine Gitea-Instanz besteht tatsächlich aus drei Komponenten, die alle synchron gehalten werden müssen:

  • Code (Git-Repositories)
  • Dateiarchiv (Anhänge, Avatare, LFS-Objekte, Indexer)
  • Datenbank (Benutzer, Issues, PRs, Einstellungen)

In unserer Testumgebung beträgt die Gesamtgröße nur etwas mehr als 700 MB:

Gitea-Plattenbelegung

Da diese drei Teile aufeinander verweisen, sind die eigenen Dokumentationen von Gitea bei der Backup-Konsistenz explizit: Die Instanz sollte während der gesamten Dauer des Backups gestoppt werden, da sonst ein Repository, das mitten in einer Migration kopiert wird, unsynchron zu dem werden kann, was die Datenbank für geschehen hält. Aus demselben Grund muss auch die Wiederherstellung als eine einzige Transaktion erfolgen.

Der einfache Weg - gitea dump

Das ist der Teil, der sich seit der vorherigen Version dieses Artikels geändert hat: Anstatt pg_dump, tar und separate Ordner manuell zu verwalten, bringt Gitea einen einzigen dump-Befehl mit, der Datenbank, Repositories, LFS-Daten, Anhänge und Konfiguration in einem Archiv bündelt.

gitea dump -c /path/to/app.ini

Dies erzeugt eine Datei mit Zeitstempel wie gitea-dump-1610949662.zip, die Folgendes enthält:

  • app.ini - Kopie der Konfigurationsdatei
  • custom/ - Anpassungen unter custom/
  • data/ - Anhänge, Avatare, LFS-Objekte, Indexer (und die SQLite-Datei, falls das Ihre Datenbank ist)
  • repos/ - Vollständige Kopie des Repository-Verzeichnisses
  • gitea-db.sql - SQL-Dump der Datenbank
  • log/ - Protokolle (nicht für die Wiederherstellung nötig)

Nützliche Schalter, die man kennen sollte:

  • --file name / -f name - Name der Ausgabedatei (- für stdout, praktisch zum direkten Weiterleiten an scp oder Objekt-Speicher)
  • --type - Ausgabeformat: zip (Standard), tar, tar.gz, tar.xz, tar.zst usw.
  • --database / -d - Erzwingt den SQL-Dialekt in gitea-db.sql (sqlite3, mysql, mssql, postgres) - nützlich bei Migrationen zwischen Datenbank-Engines
  • --skip-repository / -R, --skip-lfs-data, --skip-attachment-data, --skip-package-data, --skip-log, --skip-db - Reduziert den Dump nur auf das Nötigste
  • --tempdir / -t - Ort, an dem die temporären Dateien zwischengespeichert werden (Standard /tmp oder $TMPDIR) - Stellen Sie sicher, dass hier genügend freier Speicherplatz für die gesamte Instanz vorhanden ist

gitea dump in Docker ausführen

Da die meisten Self-Hosted-Setups Gitea über docker-compose betreiben, muss der Befehl innerhalb des Containers, als git-Benutzer und aus dem Temp-Verzeichnis des Containers ausgeführt werden:

cd ~/gitea-srv-local

# Erstellen eines Dumps innerhalb des laufenden Containers
sudo docker exec -u git -it -w /tmp gitea bash -c \
  '/usr/local/bin/gitea dump -c /data/gitea/conf/app.ini'

# Kopieren der resultierenden Zip-Datei aus dem Container
sudo docker cp gitea:/tmp/gitea-dump-*.zip ./gitea-backups/

-w /tmp ist wichtig: dump muss sein temporäres Arbeitsverzeichnis schreiben und zippen, und eine Ausführung an einem Ort ohne Schreibberechtigung schlägt mit einem Berechtigungsfehler fehl.

Dann, wie zuvor, das Archiv vom Server holen:

scp uname@gitea-srv-ip-addr:~/gitea-srv-local/gitea-backups/gitea-dump-*.zip ~/gitea-backups/

Wenn Sie die Datenbank lieber mit nativen Werkzeugen sichern (die eigenen Dokumentationen von Gitea empfehlen dies für MySQL/PostgreSQL, da der XORM-basierte SQL-Dump innerhalb von gitea dump bekannte Randfälle bei der Wiederherstellung aufweist), können Sie dies weiterhin parallel machen:

sudo docker exec -t gitea-srv-local_db_1 bash -c \
  'pg_dump gitea -U gitea --file=/var/lib/postgresql/backups/gitea-db-$(date +%Y-%m-%d).sql'

Siehe den PostgreSQL-Spickzettel für weitere pg_dump/pg_restore-Optionen und den Docker Compose-Spickzettel, falls die oben genannte docker exec/docker cp-Syntax ungewohnt wirkt.

Wie - Wiederherstellung

Eine Wiederherstellung mit nur einem Befehl gibt es immer noch nicht – die Dokumentationen von Gitea sind ehrlich, dass dies weiterhin ein manueller Prozess ist, bei dem Dateien an ihren Platz zurückbewegt und der Datenbank-Dump wiederhergestellt werden. Aber! Prüfen Sie immer zuerst das [ursprüngliche Dokument](https://docs.gitea.com/administration/backup-and-restore, da sich Pfade und Container-Layouts zwischen Versionen ändern können.

# Installieren/Starten einer frischen Gitea-Instanz (gleiche Version wie das Backup) und herunterfahren
sudo docker-compose down

# Entpacken des Dumps
unzip gitea-dump-1610949662.zip -d gitea-restore
cd gitea-restore

# Wiederherstellen von Repos und Daten in die von Gitea verwendeten Volumes
sudo cp -r repos/* ../gitea/git/
sudo cp -r data/* ../gitea/gitea/
sudo chown -R 1000:1000 ../gitea/git ../gitea/gitea

# Gitea wieder hochfahren
sudo docker-compose up -d

# Wiederherstellen der Datenbank
sudo docker exec -i gitea-srv-local_db_1 psql -U gitea gitea < gitea-db.sql

Wenn Sie die Datenbank separat mit pg_dump/pg_restore gesichert haben, stellen Sie diesen Dump auf dieselbe Weise wieder her wie bei jeder anderen Postgres-Instanz – siehe den PostgreSQL-Spickzettel für die genauen Befehle.

Hooks nach der Wiederherstellung neu generieren

Wenn Sie auf eine andere Installationsmethode (Binärdatei vs. Docker) oder einen anderen Pfad wiederhergestellt haben, zeigen die in jedem Repository eingebetteten Git-Hooks immer noch auf die alten Pfade. Korrigieren Sie dies mit:

sudo docker exec -u git -it gitea bash -c '/usr/local/bin/gitea admin regenerate hooks'

Das Überspringen dieses Schrittes ist die klassische Ursache dafür, dass push direkt nach einer Wiederherstellung fehlschlägt, ohne dass im UI ein offensichtlicher Fehler zu sehen ist.

Die Wiederherstellung überprüfen

Bevor Sie es für erledigt halten:

  1. Melden Sie sich im UI an und stellen Sie sicher, dass Benutzer, Issues und Einstellungen korrekt aussehen.
  2. Klonen Sie ein Repository und schieben Sie einen trivialen Commit, um zu bestätigen, dass die Hooks funktionieren.
  3. Führen Sie gitea doctor check aus (fügen Sie --fix hinzu, wenn etwas gemeldet wird), um Pfad- oder Berechtigungsunstimmigkeiten früh zu erkennen.

Wiederherstellung eines einzelnen Repositories - restore-repo

Der andere wirklich neue Baustein seit der letzten Version dieses Artikels ist ein Paar von Befehlen für Backup und Wiederherstellung auf Repository-Ebene, getrennt vom Workflow für die gesamte Instanz (dump/restore) oben. Sie sind praktisch, wenn Sie nur ein einzelnes Projekt wiederherstellen müssen – sagen wir, jemand hat ein Repo mit force gelöscht – anstatt den gesamten Server zurückzurollen.

dump-repo zieht ein einzelnes Repository (plus, optional, seine Issues, PRs, Wiki und andere Metadaten) in ein lokales Verzeichnis:

gitea dump-repo \
  --git_service gitea \
  --clone_addr https://gitea.example.com/owner/repo.git \
  --auth_token <token> \
  --repo_dir /backup/repos/owner/repo \
  --units wiki,issues,labels,releases,milestones,pull_requests,comments

restore-repo spielt dieses Verzeichnis dann in eine Instanz, in einen gewählten owner/repo, zurück:

gitea restore-repo \
  --repo_dir /backup/repos/owner/repo \
  --owner_name owner \
  --repo_name repo \
  --units issues,labels,milestones,pull_requests,comments

Beide --units-Listen sind optional – lassen Sie sie weg, und alles Unterstützte wird migriert. Dieses Paar ist im Kern ein Migrationswerkzeug (es funktioniert auch gegen GitHub/GitLab als Quelle über --git_service), dient aber auch gut als leichte, pro-Repo-Alternative zu einem vollständigen gitea dump, wenn eine vollständige Wiederherstellung zu viel des Guten wäre.

Automatisierung

Ein täglicher Dump plus eine Kopie auf einem anderen Server ist ein zweizeiliger Cron-Job, sobald die manuellen Schritte oben funktionieren:

# /etc/cron.d/gitea-backup
0 2 * * * root docker exec -u git -w /tmp gitea gitea dump -c /data/gitea/conf/app.ini -f - > /home/uname/gitea-backups/gitea-dump-$(date +\%F).zip 2>> /var/log/gitea-backup.log

Kombinieren Sie dies mit einer Retention-Aufräumung (find ~/gitea-backups -mtime +14 -delete) und einer Off-Site-Kopie über scp/rsync, damit ein Ausfall eines einzelnen Hosts die Backups nicht mitnimmt.

Fehlerbehebung

  • permission denied während dump – Sie führen dies nicht als git-Benutzer aus, oder --tempdir/-w zeigt auf ein Verzeichnis, in das der Container-Benutzer nicht schreiben kann.
  • Wiederherstellung erfolgreich, aber git push schlägt fehl – Hooks wurden nicht neu generiert; führen Sie gitea admin regenerate hooks aus.
  • Fehler bei der Datenbank-Wiederherstellung auf einer großen Instanz – Bevorzugen Sie native pg_dump/mysqldump gegenüber dem in gitea dump-Zip-Datei eingebetteten SQL; es ist bekannt, dass es bei der Wiederherstellung von großen oder ungewöhnlichen Schemata Schwächen hat.
  • Wiederherstellung auf eine neue Hauptversion – Führen Sie gitea doctor check --all --fix aus und prüfen Sie die Release-Notes für die Migrationsschritte dieser Version, bevor Sie annehmen, dass die Wiederherstellung abgeschlossen ist.

Für eine schnelle Referenz zu Git-Befehlen, siehe GIT-Spickzettel: Die nützlichsten GIT-Befehle.

Abonnieren

Neue Beiträge zu Systemen, Infrastruktur und KI-Engineering.