Sauvegarder et restaurer une instance gitrust¶
À qui s'adresse cette page¶
Administrateurs qui souhaitent mettre en place une sauvegarde fiable et tester la restauration. Pour comprendre la stratégie 3-2-1 adaptée à gitrust, consultez Stratégie de sauvegarde.
Ce qu'il faut sauvegarder¶
Gitrust repose sur trois sources de vérité distinctes :
| Source | Chemin / objet | Critique | Fréquence recommandée |
|---|---|---|---|
| Base de données PostgreSQL | database gitrust |
Oui | Quotidien minimum |
| Dépôts Git bare | GIT_REPOS_BASE_PATH (ex. /opt/gitrust/data/repos) |
Oui | Quotidien minimum |
| Clé SSH hôte | SSH_HOST_KEY_PATH (ex. /opt/gitrust/data/ssh_host_ed25519_key) |
Oui | Une seule fois, puis conserver |
Fichier .env |
/opt/gitrust/.env |
Oui | À chaque modification |
La clé SSH hôte est immuable après le premier démarrage. Si vous la perdez, tous vos utilisateurs devront supprimer leur entrée
known_hostset re-vérifier le fingerprint.
Sauvegarder¶
Sauvegarde PostgreSQL (pg_dump)¶
BACKUP_DIR="/var/backups/gitrust"
DATE=$(date +%Y%m%d-%H%M%S)
mkdir -p "$BACKUP_DIR"
pg_dump \
-h localhost \
-U gitrust \
--format=custom \
--file="${BACKUP_DIR}/pg-${DATE}.dump" \
gitrust
echo "Dump : ${BACKUP_DIR}/pg-${DATE}.dump"
# Purger les sauvegardes de plus de 30 jours
find "$BACKUP_DIR" -name "pg-*.dump" -mtime +30 -delete
Le format --format=custom est compressé et restaurable avec pg_restore. Le fichier contient la structure ET les données.
Sauvegarde des dépôts bare (rsync)¶
REPOS_SRC="/opt/gitrust/data/repos"
REPOS_DST="/var/backups/gitrust/repos"
rsync \
--archive \
--delete \
--hard-links \
--checksum \
"${REPOS_SRC}/" "${REPOS_DST}/"
Les dépôts bare Git sont consistants en lecture même pendant un git push actif : Git garantit l'atomicité au niveau du pack.
Sauvegarde de la clé SSH hôte et du .env¶
BACKUP_DIR="/var/backups/gitrust"
DATE=$(date +%Y%m%d-%H%M%S)
tar czf "${BACKUP_DIR}/config-${DATE}.tar.gz" \
/opt/gitrust/data/ssh_host_ed25519_key \
/opt/gitrust/data/ssh_host_ed25519_key.pub \
/opt/gitrust/.env
chmod 600 "${BACKUP_DIR}/config-${DATE}.tar.gz"
Script complet backup.sh¶
#!/usr/bin/env bash
# /opt/gitrust/scripts/backup.sh
set -euo pipefail
BACKUP_DIR="${BACKUP_DIR:-/var/backups/gitrust}"
DATE=$(date +%Y%m%d-%H%M%S)
PG_USER="gitrust"
PG_DB="gitrust"
REPOS_SRC="/opt/gitrust/data/repos"
SSH_KEY="/opt/gitrust/data/ssh_host_ed25519_key"
ENV_FILE="/opt/gitrust/.env"
mkdir -p "$BACKUP_DIR"
echo "[1/3] Dump PostgreSQL..."
pg_dump -U "$PG_USER" --format=custom \
--file="${BACKUP_DIR}/pg-${DATE}.dump" "$PG_DB"
echo "[2/3] Rsync dépôts bare..."
mkdir -p "${BACKUP_DIR}/repos"
rsync --archive --delete --checksum \
"${REPOS_SRC}/" "${BACKUP_DIR}/repos/"
echo "[3/3] Archive config sensible..."
tar czf "${BACKUP_DIR}/config-${DATE}.tar.gz" \
"$SSH_KEY" "${SSH_KEY}.pub" "$ENV_FILE"
chmod 600 "${BACKUP_DIR}/config-${DATE}.tar.gz"
echo "Sauvegarde terminée dans $BACKUP_DIR"
find "$BACKUP_DIR" -name "pg-*.dump" -mtime +30 -delete
find "$BACKUP_DIR" -name "config-*.tar.gz" -mtime +90 -delete
Planifier via cron :
# Sauvegarder chaque nuit à 2h00
0 2 * * * /opt/gitrust/scripts/backup.sh >> /var/log/gitrust-backup.log 2>&1
Restaurer¶
Avant toute restauration¶
# 1. Arrêter gitrust
sudo systemctl stop gitrust # ou : docker compose stop gitrust
# 2. Vérifier les fichiers de sauvegarde disponibles
ls -lh /var/backups/gitrust/pg-*.dump | tail -5
ls -lh /var/backups/gitrust/config-*.tar.gz | tail -3
du -sh /var/backups/gitrust/repos/
Restaurer la base PostgreSQL¶
DUMP="/var/backups/gitrust/pg-20260417-020000.dump"
sudo -u postgres psql -c "DROP DATABASE IF EXISTS gitrust;"
sudo -u postgres psql -c "CREATE DATABASE gitrust OWNER gitrust;"
pg_restore \
-h localhost \
-U gitrust \
--dbname=gitrust \
--verbose \
"$DUMP"
Vérification :
psql "postgres://gitrust:MOT_DE_PASSE@localhost:5432/gitrust" \
-c "SELECT COUNT(*) FROM users; SELECT COUNT(*) FROM repositories;"
Restaurer les dépôts bare¶
REPOS_SRC="/var/backups/gitrust/repos"
REPOS_DST="/opt/gitrust/data/repos"
rsync --archive --delete "${REPOS_SRC}/" "${REPOS_DST}/"
sudo chown -R gitrust:gitrust "${REPOS_DST}"
Restaurer la clé SSH hôte et le .env¶
ARCHIVE="/var/backups/gitrust/config-20260417-020000.tar.gz"
sudo tar xzf "$ARCHIVE" -C /
sudo chown gitrust:gitrust /opt/gitrust/data/ssh_host_ed25519_key*
sudo chmod 600 /opt/gitrust/data/ssh_host_ed25519_key
sudo chmod 644 /opt/gitrust/data/ssh_host_ed25519_key.pub
sudo chmod 600 /opt/gitrust/.env
Redémarrer et vérifier¶
sudo systemctl start gitrust
sleep 3
curl -s -o /dev/null -w "%{http_code}" http://localhost:4000/
# Attendu : 302
Tester la restauration (drill trimestriel)¶
Une sauvegarde non testée n'est pas une sauvegarde. Testez sur une VM distincte :
# Sur une VM de test vierge — restaurer, puis vérifier :
git clone ssh://git@VM_TEST:2222/admin/un-depot-connu.git /tmp/drill-test
ls /tmp/drill-test/
# Les fichiers doivent correspondre à l'état au moment de la sauvegarde