Doku erstellt
This commit is contained in:
@@ -0,0 +1,106 @@
|
|||||||
|
# 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:40]
|
||||||
|
|
||||||
|
## 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 mit SQLite ist der eingebaute Befehl `gitea dump` die sauberste Backup-Methode. Laut Gitea-Dokumentation enthält der Dump die Datenbank, Repositories, Konfiguration und weitere Instanzdaten in einem Archiv.[web:1]
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
## Backup im laufenden Betrieb
|
||||||
|
|
||||||
|
Der Backup-Befehl für die vorliegende Konfiguration lautet:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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]
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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 für Portainer CE
|
||||||
|
|
||||||
|
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 Backup-Verzeichnis und löscht alte Sicherungen automatisch.[web:1][web:40]
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BACKUP_DIR="/backup/gitea"
|
||||||
|
DATA_DIR="/home/hans/forgejo/data"
|
||||||
|
CONTAINER_NAME="forgejo"
|
||||||
|
RETENTION_DAYS=14
|
||||||
|
|
||||||
|
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"
|
||||||
|
find "$BACKUP_DIR" -name 'gitea-dump-*.zip' -mtime +$RETENTION_DAYS -delete
|
||||||
|
```
|
||||||
|
|
||||||
|
Empfohlener Speicherort ist `/usr/local/bin/gitea-backup.sh`. Das Skript sollte nur für root schreibbar sein.
|
||||||
|
|
||||||
|
## Zeitgesteuerte Ausführung
|
||||||
|
|
||||||
|
Da Portainer CE keine Business-Scheduled-Tasks bereitstellt, ist ein Cronjob auf dem Host der robuste Standardweg.[web:40]
|
||||||
|
|
||||||
|
```cron
|
||||||
|
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 oder Exit-Code, damit fehlgeschlagene Backups 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]
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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 wird üblicherweise mit Zugriff auf den Docker-Socket betrieben. Dadurch ist Portainer ein mächtiges Verwaltungswerkzeug, aber auch sicherheitsrelevant und sollte per HTTPS und mit restriktivem Zugriff betrieben werden.[web:40]
|
||||||
|
|
||||||
|
Außerdem sollten Backups nicht nur lokal auf demselben Host liegen. Ein zusätzliches Ziel wie NAS, rsync-Backup oder S3-kompatibler Storage reduziert das Risiko bei Host-Ausfall erheblich.
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# README.md
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Dieses Projekt beschreibt den Betrieb einer selbstgehosteten Gitea-Instanz in Docker Compose, verwaltet über Portainer Community Edition. Die Instanz verwendet ein Host-Bind-Mount für `/data`, SQLite als Datenbank und einen dedizierten Container-Namen (`forgejo`), wodurch Backups und Restore auf Host-Ebene einfach umsetzbar sind.
|
||||||
|
|
||||||
|
## Architektur
|
||||||
|
|
||||||
|
Der Stack besteht aus einem einzelnen Gitea-Container auf Basis von `gitea/gitea:latest`, der die Weboberfläche auf Port 3000 und SSH für Git-Zugriffe auf Port 922 veröffentlicht. Die persistenten Daten liegen im Host-Verzeichnis `/home/hans/forgejo/data`, das in den Container nach `/data` gemountet wird.
|
||||||
|
|
||||||
|
| Komponente | Wert |
|
||||||
|
|---|---|
|
||||||
|
| Orchestrierung | Docker Compose |
|
||||||
|
| Verwaltung | Portainer Community Edition |
|
||||||
|
| Container-Name | `forgejo` |
|
||||||
|
| Service-Name | `server` |
|
||||||
|
| Image | `gitea/gitea:latest` |
|
||||||
|
| Datenbank | SQLite |
|
||||||
|
| Persistenz | Bind-Mount `/home/hans/forgejo/data:/data` |
|
||||||
|
| HTTP | `3000:3000` |
|
||||||
|
| SSH | `922:22` |
|
||||||
|
|
||||||
|
## Verzeichnisstruktur
|
||||||
|
|
||||||
|
Eine saubere Host-Struktur vereinfacht Betrieb, Backup und Migration. Für dieses Setup bietet sich folgende Struktur an:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/home/hans/forgejo/
|
||||||
|
├── docker-compose.yml
|
||||||
|
├── .env
|
||||||
|
├── secrets/
|
||||||
|
│ └── smtp_password.txt
|
||||||
|
└── data/
|
||||||
|
```
|
||||||
|
|
||||||
|
Zusätzlich sollte ein separates Backup-Ziel außerhalb des Live-Datenpfads verwendet werden:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/backup/gitea/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Start und Betrieb
|
||||||
|
|
||||||
|
Der Stack kann direkt per Compose oder über Portainer Stacks verwaltet werden. Für einen CLI-basierten Betrieb sind die üblichen Compose-Befehle ausreichend.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
docker compose logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Wenn Portainer verwendet wird, sollte Portainer nur als Verwaltungsoberfläche dienen, während Automatisierung wie Backups, Rotation und Offsite-Sync weiterhin hostseitig per Cron oder Systemd Timer läuft.[web:40]
|
||||||
|
|
||||||
|
## Backup
|
||||||
|
|
||||||
|
Für Gitea in Docker ist `gitea dump` die offizielle Backup-Methode. Laut Gitea-Dokumentation enthält der Dump Datenbank, Repositories, Konfiguration und weitere relevante Instanzdaten in einem Archiv.[web:1]
|
||||||
|
|
||||||
|
In diesem Projekt wird Portainer Community Edition ohne Business-Features verwendet. Da CE keine nativen Scheduled Tasks wie die Business Edition bereitstellt, sollte das Backup per Host-Cronjob umgesetzt werden.[web:40]
|
||||||
|
|
||||||
|
### Manueller Dump
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automatisierung
|
||||||
|
|
||||||
|
Die empfohlene operative Dokumentation liegt in der beigefügten Backup-Anleitung.
|
||||||
|
|
||||||
|
[code_file:42]
|
||||||
|
|
||||||
|
## Restore
|
||||||
|
|
||||||
|
Ein Restore erfolgt manuell durch Stoppen des Containers, Entpacken des Dumps und Zurückkopieren der Daten in das Host-Verzeichnis. Laut Gitea-Dokumentation sollten nach dem Restore die Git-Hooks neu generiert werden, damit Repository-Operationen wieder sauber funktionieren.[web:1]
|
||||||
|
|
||||||
|
## Sicherheit
|
||||||
|
|
||||||
|
In produktionsnahen Setups sollten keine Secrets im Klartext in der Compose-Datei stehen. Für SMTP- oder andere Zugangsdaten sind `.env` mit restriktiven Rechten oder Docker-Secrets die bessere Wahl als direkte Environment-Werte in der Stack-Datei.
|
||||||
|
|
||||||
|
Außerdem sollte das Projekt nicht dauerhaft auf `gitea/gitea:latest` laufen. Für reproduzierbare Deployments sind feste Versionstags und ein geplanter Update-Prozess die robustere Variante.
|
||||||
|
|
||||||
|
## Betriebsempfehlungen
|
||||||
|
|
||||||
|
- SSH nur mit Schlüsseln erlauben und keinen Root-Login per SSH zulassen.
|
||||||
|
- Portainer nur per HTTPS und mit starkem Zugangsschutz betreiben.[web:40]
|
||||||
|
- Backups regelmäßig auf Restore testen.[web:1]
|
||||||
|
- Backups zusätzlich offsite sichern, etwa per rsync auf NAS oder auf S3-kompatiblen Storage.
|
||||||
|
- Updates von Ubuntu, Docker Engine und Container-Images geplant und nachvollziehbar durchführen.
|
||||||
|
|
||||||
|
## Nächste Schritte
|
||||||
|
|
||||||
|
Für den weiteren Ausbau dieses Projekts sind folgende Punkte sinnvoll:
|
||||||
|
|
||||||
|
- `.env` und Secrets aus der Compose-Datei auslagern.
|
||||||
|
- `latest` durch einen festen Gitea-Versionstag ersetzen.
|
||||||
|
- Cronjob oder Systemd-Timer für Backups einrichten.
|
||||||
|
- Optional Offsite-Backup per rsync oder rclone ergänzen.
|
||||||
|
- Reverse Proxy und TLS für externen Zugriff ergänzen.
|
||||||
Reference in New Issue
Block a user