forgejo dump crée un fichier ZIP unique qui contient tout : la base de données, les dépôts Git,
la configuration, les clés SSH, les avatars et les données LFS. Cette page explique comment
créer, vérifier et restaurer ce backup, avec une automatisation cron pour ne plus y penser.
La procédure a été testée en lab : une instance Forgejo 14.0.3 sauvegardée, complètement détruite et restaurée depuis le ZIP. Résultat : HTTP 200, dépôts et configuration intacts.
Ce que contient un backup Forgejo
Section intitulée « Ce que contient un backup Forgejo »forgejo dump produit un fichier .zip unique, sans dépendance à un outil externe. Connaître sa structure sert à deux choses : vérifier qu'un backup est complet avant de compter dessus, et savoir quoi restaurer où le jour de l'incident. Voici le contenu type :
| Fichier dans le ZIP | Contenu |
|---|---|
app.ini | Fichier de configuration principal |
forgejo-db.sql | Export SQL complet de la base de données |
data/ | Queues, indexeurs, LFS, clés SSH, avatars, sessions |
repos/ | Tous les dépôts Git (format bare) |
Préparer le répertoire de backup
Section intitulée « Préparer le répertoire de backup »forgejo dump écrit son archive sous l'identité de l'utilisateur git, celui qui fait tourner le service. Le répertoire de destination doit donc lui appartenir avant la première exécution, faute de quoi la commande échoue au moment d'écrire le fichier, après avoir déjà travaillé plusieurs minutes. Le mode 750 évite qu'un utilisateur non privilégié puisse lire une archive contenant la base et les clés SSH.
sudo mkdir -p /var/lib/forgejo/backupssudo chown git:git /var/lib/forgejo/backupssudo chmod 750 /var/lib/forgejo/backupsCréer un backup
Section intitulée « Créer un backup »Deux modes coexistent, et le choix ne dépend que de votre tolérance à l'interruption. Service arrêté, l'archive est cohérente par construction : rien n'écrit pendant la copie. Service en marche, vous évitez la coupure mais acceptez qu'une écriture en cours ne soit pas dans l'archive. Les deux commandes sont identiques, seul l'arrêt préalable du service change.
Backup manuel (service arrêté – recommandé)
Section intitulée « Backup manuel (service arrêté – recommandé) »Arrêter le service garantit la cohérence des données, notamment pour SQLite qui n'a pas de mécanisme de snapshot transactionnel externe.
# Arrêter le servicesudo systemctl stop forgejo.service
# Créer le backupsudo -u git forgejo dump \ -w /var/lib/forgejo \ -c /etc/forgejo/app.ini \ -f /var/lib/forgejo/backups/forgejo-dump-$(date +%Y%m%d-%H%M).zip
# Vérifier le fichier crééls -lh /var/lib/forgejo/backups/
# Relancer le servicesudo systemctl start forgejo.serviceUn backup d'une instance vide pèse environ 2 Mo. Avec des dépôts réels, la taille correspond à la somme des dépôts + les données LFS.
Backup à chaud (service en cours)
Section intitulée « Backup à chaud (service en cours) »Forgejo permet de créer un backup sans arrêter le service. Ce mode convient aux instances très actives qui ne peuvent pas tolérer une interruption, au prix d'un risque (très faible) d'incohérence des données en cours d'écriture.
sudo -u git forgejo dump \ -w /var/lib/forgejo \ -c /etc/forgejo/app.ini \ -f /var/lib/forgejo/backups/forgejo-hot-$(date +%Y%m%d-%H%M).zipVérifier le contenu d'un backup
Section intitulée « Vérifier le contenu d'un backup »unzip -l liste l'archive sans l'extraire : si app.ini, forgejo-db.sql et repos/ n'apparaissent pas tous les trois, le backup est inexploitable et il ne faut pas attendre le jour de la panne pour s'en apercevoir.
# Lister les fichiers dans le ZIPunzip -l /var/lib/forgejo/backups/forgejo-dump-20260328-1200.zip | head -30
# Vérifier que les éléments essentiels sont présentsunzip -l /var/lib/forgejo/backups/forgejo-dump-20260328-1200.zip | grep -E "app.ini|forgejo-db.sql|repos/"Automatiser avec cron
Section intitulée « Automatiser avec cron »Un backup manuel finit toujours par être oublié. Le script ci-dessous enchaîne les quatre gestes de la sauvegarde nocturne : arrêt du service, dump, redémarrage, purge des archives au-delà de la rétention. Il tourne sous root parce qu'il pilote systemctl, et il redescend sur l'utilisateur git pour la seule commande qui l'exige.
Script de backup
Section intitulée « Script de backup »Le set -e en tête est ce qui empêche le pire scénario : sans lui, un échec du dump serait quand même suivi de la purge, qui effacerait les seules archives encore valides. Contrepartie à connaître : si le dump échoue, le script s'arrête avant systemctl start et Forgejo reste éteint, d'où l'intérêt de surveiller le fichier de log.
sudo tee /usr/local/bin/forgejo-backup.sh << 'EOF'#!/bin/bashset -e
BACKUP_DIR="/var/lib/forgejo/backups"FORGEJO_WORK="/var/lib/forgejo"FORGEJO_CONF="/etc/forgejo/app.ini"RETENTION_DAYS=30LOG="/var/log/forgejo-backup.log"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Début du backup Forgejo" >> "$LOG"
# Arrêt du servicesystemctl stop forgejo.service
# BackupBACKUP_FILE="${BACKUP_DIR}/forgejo-$(date +%Y%m%d-%H%M).zip"sudo -u git forgejo dump \ -w "$FORGEJO_WORK" \ -c "$FORGEJO_CONF" \ -f "$BACKUP_FILE"
# Redémarragesystemctl start forgejo.service
# Nettoyage des anciens backupsfind "$BACKUP_DIR" -name "forgejo-*.zip" -mtime "+${RETENTION_DAYS}" -delete
SIZE=$(du -sh "$BACKUP_FILE" | cut -f1)echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup terminé : $BACKUP_FILE ($SIZE)" >> "$LOG"EOF
sudo chmod 750 /usr/local/bin/forgejo-backup.shPlanification cron (toutes les nuits à 2h)
Section intitulée « Planification cron (toutes les nuits à 2h) »La planification se fait dans le crontab de root, pas dans celui de git : le script appelle systemctl stop et systemctl start, hors de portée d'un utilisateur non privilégié.
# Ouvrir le crontab root (le script utilise systemctl qui nécessite root)sudo crontab -eAjoutez la ligne :
0 2 * * * /usr/local/bin/forgejo-backup.shVérifier les logs de sauvegarde
Section intitulée « Vérifier les logs de sauvegarde »Chaque exécution ajoute deux lignes horodatées : un début et une fin avec la taille de l'archive. Une ligne de début sans ligne de fin correspondante signale un dump interrompu, donc un service potentiellement resté arrêté.
cat /var/log/forgejo-backup.logRestaurer depuis un backup
Section intitulée « Restaurer depuis un backup »La restauration écrase les données en place, elle ne fusionne rien : lancez-la sur une instance dont vous acceptez de perdre l'état courant. L'ordre des étapes n'est pas indifférent, le service doit être arrêté avant l'extraction et redémarré seulement une fois app.ini et data/ remis en place. Le point qui fait échouer la plupart des restaurations est la propriété des fichiers : tout ce qui est extrait ou copié doit appartenir à l'utilisateur git, sinon Forgejo redémarre sans accéder à ses propres dépôts.
-
Préparer la restauration
La restauration écrase les données existantes. Si votre instance est en production, assurez-vous d'avoir communiqué une fenêtre de maintenance.
Fenêtre de terminal sudo systemctl stop forgejo.service -
Extraire le backup
Le répertoire d'extraction doit appartenir à l'utilisateur
git, sinon la restauration produira des fichiers avec de mauvaises permissions.Fenêtre de terminal BACKUP_FILE="/var/lib/forgejo/backups/forgejo-20260328-1200.zip"RESTORE_DIR="/tmp/forgejo-restore"# Créer le répertoire avec les bons droitssudo rm -rf "$RESTORE_DIR"sudo mkdir "$RESTORE_DIR"sudo chown git:git "$RESTORE_DIR"# Extrairesudo -u git unzip -q "$BACKUP_FILE" -d "$RESTORE_DIR"# Vérifierls "$RESTORE_DIR"# Doit afficher : app.ini data/ repos/ forgejo-db.sql -
Restaurer la configuration
Fenêtre de terminal sudo cp "$RESTORE_DIR/app.ini" /etc/forgejo/app.inisudo chown git:git /etc/forgejo/app.inisudo chmod 640 /etc/forgejo/app.ini -
Restaurer les données
rsync -apréserve les permissions et écrase les fichiers existants :Fenêtre de terminal sudo rsync -a --chown=git:git "$RESTORE_DIR/data/" /var/lib/forgejo/data/Si le répertoire
repos/du backup est distinct dedata/forgejo-repositories/:Fenêtre de terminal sudo rsync -a --chown=git:git "$RESTORE_DIR/repos/" \/var/lib/forgejo/data/forgejo-repositories/ -
Relancer le service et vérifier
Fenêtre de terminal sudo systemctl start forgejo.servicesudo systemctl status forgejo.service# Test HTTPcurl -o /dev/null -sw "%{http_code}" http://localhost:3000/# Doit afficher 200 -
Nettoyer les fichiers temporaires
Fenêtre de terminal sudo rm -rf /tmp/forgejo-restore
Stratégie de rétention
Section intitulée « Stratégie de rétention »La fréquence se déduit de la question « combien de travail acceptez-vous de perdre », la rétention de « jusqu'à quand pourriez-vous devoir remonter ». Une corruption silencieuse ou une suppression de dépôt passée inaperçue se découvre parfois des semaines plus tard, ce qui justifie de garder un point hebdomadaire au-delà des sauvegardes quotidiennes. Ces valeurs sont des points de départ à ajuster.
| Volume de changements | Fréquence backup | Rétention |
|---|---|---|
| Petite instance, peu de commits | Quotidien | 30 jours |
| Instance active (>10 développeurs) | 2x/jour | 14 jours + backup hebdo 3 mois |
| Instance critique | Toutes les heures (hot) | 7 jours + backup quotidien 1 mois |
Externalisez les backups : copiez les ZIP vers un stockage distant (S3, NFS, autre serveur) pour vous protéger contre la perte du serveur Forgejo lui-même.
Dépannage
Section intitulée « Dépannage »Les trois pannes ci-dessous ont la même origine : un décalage entre l'utilisateur qui exécute la commande et le propriétaire des fichiers. Forgejo travaille sous git, les commandes d'administration sous root, et chaque sudo mal placé produit un répertoire que l'autre ne peut plus écrire. Le réflexe de diagnostic est toujours ls -la sur le répertoire concerné.
permission denied lors de forgejo dump
Section intitulée « permission denied lors de forgejo dump »Le répertoire de destination appartient encore à root : forgejo dump prépare l'archive puis échoue au moment de l'écrire.
ls -la /var/lib/forgejo/backups/# Vérifier que le répertoire appartient à gitsudo chown git:git /var/lib/forgejo/backupsunzip: cannot create file lors de la restauration
Section intitulée « unzip: cannot create file lors de la restauration »Même cause côté restauration : sudo -u git unzip ne peut rien créer dans un répertoire d'extraction resté la propriété de root.
# Vérifier les droits du répertoire d'extractionls -la /tmp/forgejo-restore/sudo chown git:git /tmp/forgejo-restore/La restauration ne trouve pas les dépôts
Section intitulée « La restauration ne trouve pas les dépôts »Vérifiez que REPOSITORY_ROOT dans app.ini correspond au chemin où vous avez restauré
les dépôts :
sudo grep -A5 "^\[repository\]" /etc/forgejo/app.ini# ROOT = /var/lib/forgejo/data/forgejo-repositoriesÀ retenir
Section intitulée « À retenir »forgejo dumpproduit un ZIP complet : config, DB SQL, dépôts, LFS, avatars- Le répertoire de destination du backup doit appartenir à l'utilisateur
git - Le service doit être arrêté pour un backup cohérent (surtout avec SQLite)
- La restauration suit le principe : extraire (en tant que
git) → copierapp.ini→ rsyncdata/→ démarrer - Avec PostgreSQL/MySQL, la base de données n'est pas dans le ZIP, sauvegardez-la séparément
- Externaliser les backups est indispensable pour se protéger d'une perte serveur