Files
docker-gitea/BACKUP.md
T

6.9 KiB

BACKUP.md

Gitea-Backup mit Portainer Community Edition

Diese Anleitung beschreibt ein praxistaugliches Backup für eine Gitea-Instanz, die per Docker Compose bereitgestellt und über Portainer Community Edition verwaltet wird. Portainer CE bietet keine nativen Scheduled Tasks wie die Business Edition, daher sollte das eigentliche Backup über den Docker-Host per Cron ausgeführt werden.[web:62][web:65]

Ausgangslage

In der gezeigten Compose-Datei läuft Gitea als Service server mit dem Container-Namen forgejo, und das Verzeichnis /data im Container ist als Bind-Mount auf /home/hans/forgejo/data auf dem Host gelegt. Dadurch kann ein im Container erzeugtes Backup direkt auf dem Host-Dateisystem abgelegt und dort weiterverarbeitet werden.

Empfohlene Methode

Für eine Gitea-Instanz ist der eingebaute Befehl gitea dump die offizielle Backup-Methode. Laut Gitea-Dokumentation enthält der Dump Datenbank, Repositories, Konfiguration und weitere Instanzdaten in einem Archiv.[web:1][web:13]

Gleichzeitig weist die Gitea-Dokumentation darauf hin, dass für vollständige Konsistenz die Instanz während des Backups gestoppt werden sollte, weil Datenbank, Dateien und Repositories sich während des Betriebs ändern können.[web:1][web:13]

Für die vorliegende Portainer-CE-Variante ist deshalb folgendes Vorgehen praxisnah:

  • Standardfall: gitea dump im laufenden Betrieb, wenn eine kleine Inkonsistenz im Fehlerfall tolerierbar ist.[web:1]
  • Strenger Fall: Container kurz stoppen, Backup erstellen, Container wieder starten, wenn maximale Konsistenz wichtiger ist.[web:1]
  • Offsite-Fall: das lokal erzeugte ZIP anschließend per rsync über SSH auf einen zweiten Rechner übertragen.[web:61][web:63]

Backup im laufenden Betrieb

Der Backup-Befehl für die vorliegende Konfiguration lautet:

docker exec -u git -w /data forgejo   /app/gitea/gitea dump -c /data/gitea/conf/app.ini   --file /data/gitea-dump-$(date +%Y%m%d-%H%M).zip

Da /data auf /home/hans/forgejo/data gemountet ist, liegt die erzeugte ZIP-Datei anschließend direkt auf dem Host. Das vereinfacht Rotation, Kopieren auf ein NAS und Restore-Tests deutlich.

Backup mit kurzer Downtime

Wenn das Backup konsistent sein muss, sollte Gitea laut offizieller Dokumentation während der Sicherung gestoppt werden.[web:1]

docker stop forgejo

docker run --rm   -v /home/hans/forgejo/data:/data   -u 1000:1000   gitea/gitea:latest   /app/gitea/gitea dump -c /data/gitea/conf/app.ini --file /data/gitea-dump-$(date +%Y%m%d-%H%M).zip

docker start forgejo

Diese Variante minimiert Race Conditions zwischen SQLite-Datei, Repositories und Metadaten. Für produktionsnahe Setups ist sie die konservativere und technisch sauberere Lösung.[web:1]

Backup-Skript mit rsync-Offsite-Kopie

Das folgende Skript ist für Portainer CE geeignet, weil es unabhängig von Portainer direkt auf dem Docker-Host läuft. Es erstellt den Dump, verschiebt ihn in ein separates lokales Backup-Verzeichnis, überträgt ihn danach per rsync auf einen zweiten Rechner und löscht lokale Altbestände automatisch.[web:1][web:61][web:63][web:66]

#!/bin/bash
set -euo pipefail

BACKUP_DIR="/backup/gitea"
DATA_DIR="/home/hans/forgejo/data"
CONTAINER_NAME="forgejo"
RETENTION_DAYS=14

REMOTE_USER="backup"
REMOTE_HOST="192.168.1.50"
REMOTE_DIR="/srv/backup/gitea"
SSH_KEY="/root/.ssh/id_ed25519_gitea_backup"
SSH_OPTS="-i ${SSH_KEY} -o BatchMode=yes -o StrictHostKeyChecking=yes"

mkdir -p "$BACKUP_DIR"
TIMESTAMP=$(date +%Y%m%d-%H%M)
TMP_FILE="$DATA_DIR/gitea-dump.zip"
FINAL_FILE="$BACKUP_DIR/gitea-dump-$TIMESTAMP.zip"

/usr/bin/docker exec -u git -w /data "$CONTAINER_NAME"   /app/gitea/gitea dump -c /data/gitea/conf/app.ini   --file /data/gitea-dump.zip

mv "$TMP_FILE" "$FINAL_FILE"
chmod 600 "$FINAL_FILE"

rsync -a --partial --human-readable --mkpath   -e "ssh ${SSH_OPTS}"   "$FINAL_FILE"   "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/"

find "$BACKUP_DIR" -name 'gitea-dump-*.zip' -mtime +$RETENTION_DAYS -delete

rsync -a läuft im Archivmodus und erhält Attribute, während --partial unvollständige Übertragungen für spätere Wiederaufnahme stehen lässt. --mkpath kann das Zielverzeichnis auf dem Remote-System automatisch anlegen, sofern die eingesetzte rsync-Version diese Option unterstützt.[web:61][web:63][web:66]

Da das Gitea-Backup bereits als ZIP vorliegt, bringt -z für zusätzliche Transportkompression meist wenig. Auf langsamen WAN-Strecken kann es trotzdem getestet werden, auf schnellen LAN-Verbindungen ist es meist entbehrlich.[web:63][web:66]

SSH-Vorbereitung

Für Cronjobs sollte ein dedizierter SSH-Schlüssel ohne Passworteingabe verwendet werden. Zusätzlich sollte der Host-Key des Zielsystems vorab in known_hosts eingetragen werden, damit StrictHostKeyChecking=yes im unbeaufsichtigten Betrieb nicht blockiert.[web:63]

ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519_gitea_backup
ssh-keyscan -H 192.168.1.50 >> /root/.ssh/known_hosts
ssh-copy-id -i /root/.ssh/id_ed25519_gitea_backup.pub backup@192.168.1.50

Auf dem Zielhost sollte das Backup-Verzeichnis dem dedizierten Backup-User gehören und nicht allgemein schreibbar sein.

sudo mkdir -p /srv/backup/gitea
sudo chown backup:backup /srv/backup/gitea
chmod 700 /srv/backup/gitea

Zeitgesteuerte Ausführung

Da Portainer CE keine Business-Scheduled-Tasks bereitstellt, ist ein Cronjob auf dem Host der robuste Standardweg.[web:62][web:65]

30 2 * * * root /usr/local/bin/gitea-backup.sh >> /var/log/gitea-backup.log 2>&1

Zusätzlich sinnvoll ist ein Monitoring auf Datei-Alter, Exit-Code und rsync-Fehler, damit fehlgeschlagene Backups oder unterbrochene Offsite-Übertragungen nicht unbemerkt bleiben.

Restore

Gitea bietet keinen automatischen Restore-Befehl; die Wiederherstellung ist laut Dokumentation ein manueller Prozess. Nach dem Zurückspielen der Daten sollten die Git-Hooks neu generiert werden, damit Pushes wieder korrekt funktionieren.[web:1][web:13]

docker stop forgejo
cd /tmp
unzip /backup/gitea/gitea-dump-YYYYMMDD-HHMM.zip
rm -rf /home/hans/forgejo/data/*
cp -a data/* /home/hans/forgejo/data/
cp -a repos/* /home/hans/forgejo/data/git/repositories/
chown -R 1000:1000 /home/hans/forgejo/data

docker start forgejo
docker exec -u git forgejo /app/gitea/gitea -c /data/gitea/conf/app.ini admin regenerate hooks

Ein Restore sollte regelmäßig in einer Testumgebung geprüft werden. Nur ein erfolgreich getesteter Restore ist ein verlässliches Backup.[web:1]

Härtung

Portainer ist ein mächtiges Verwaltungswerkzeug und sollte nur restriktiv erreichbar sein. Für produktionsnahe Setups sind HTTPS, starke Authentisierung und ein minimaler administrativer Zugriff sinnvoll.[web:68]

Zusätzlich sollten Backups nicht nur lokal auf demselben Host liegen. Eine zusätzliche Kopie auf einem zweiten Rechner per rsync über SSH reduziert das Risiko bei Host-Ausfall, Dateisystemfehlern oder versehentlichem Löschen deutlich.[web:61][web:63]