Restructure project following production-ready standards
- Add comprehensive docker-compose configuration with health checks - Create Makefile with 16 utility commands for easy management - Implement robust backup/restore/update scripts with error handling - Add optimized PostgreSQL configuration for Gitea workload - Enhance .env.example with clear dev/prod sections and documentation - Create comprehensive README with installation, configuration, and maintenance guides - Improve .gitignore to exclude all sensitive and generated files - Add Redis persistence (AOF) and memory limits - Configure service dependencies with health conditions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
121
scripts/backup.sh
Executable file
121
scripts/backup.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
# ============================================
|
||||
# Script de sauvegarde Gitea
|
||||
# ============================================
|
||||
# Ce script crée une sauvegarde complète de:
|
||||
# - Base de données PostgreSQL
|
||||
# - Dépôts Git
|
||||
# - Configuration Gitea
|
||||
# - Données utilisateur
|
||||
|
||||
set -e # Arrêter en cas d'erreur
|
||||
|
||||
# Couleurs pour l'affichage
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Charger les variables d'environnement
|
||||
if [ -f .env ]; then
|
||||
source .env
|
||||
else
|
||||
echo -e "${RED}Erreur: Fichier .env non trouvé${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Variables
|
||||
BACKUP_DIR="./backups"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_NAME="gitea_backup_${TIMESTAMP}"
|
||||
TEMP_DIR="${BACKUP_DIR}/${BACKUP_NAME}"
|
||||
RETENTION_DAYS=${BACKUP_RETENTION_DAYS:-7}
|
||||
|
||||
# Vérifier que les variables nécessaires sont définies
|
||||
if [ -z "$POSTGRES_DATABASE" ] || [ -z "$POSTGRES_USER" ] || [ -z "$POSTGRES_PASSWORD" ]; then
|
||||
echo -e "${RED}Erreur: Variables PostgreSQL non définies dans .env${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fonction de nettoyage en cas d'erreur
|
||||
cleanup() {
|
||||
if [ -d "$TEMP_DIR" ]; then
|
||||
echo -e "${YELLOW}Nettoyage des fichiers temporaires...${NC}"
|
||||
rm -rf "$TEMP_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# Piège pour nettoyer en cas d'erreur
|
||||
trap cleanup EXIT
|
||||
|
||||
echo -e "${GREEN}=== Début de la sauvegarde Gitea ===${NC}"
|
||||
echo "Timestamp: $TIMESTAMP"
|
||||
|
||||
# Créer les répertoires si nécessaire
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
|
||||
# Vérifier que les conteneurs sont en cours d'exécution
|
||||
if ! docker compose ps | grep -q "gitea.*running"; then
|
||||
echo -e "${RED}Erreur: Le conteneur Gitea n'est pas en cours d'exécution${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[1/4] Sauvegarde de la base de données PostgreSQL...${NC}"
|
||||
# Exporter la base de données
|
||||
export PGPASSWORD="$POSTGRES_PASSWORD"
|
||||
docker compose exec -T db pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DATABASE" \
|
||||
--format=custom \
|
||||
--compress=9 \
|
||||
--no-owner \
|
||||
--no-acl \
|
||||
> "${TEMP_DIR}/database.dump"
|
||||
|
||||
if [ ! -s "${TEMP_DIR}/database.dump" ]; then
|
||||
echo -e "${RED}Erreur: Le dump de la base de données est vide${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Base de données sauvegardée${NC}"
|
||||
|
||||
echo -e "${YELLOW}[2/4] Sauvegarde des dépôts Git et données...${NC}"
|
||||
# Créer une archive des dépôts et données
|
||||
docker compose exec -T gitea tar czf - \
|
||||
-C /data \
|
||||
--exclude='./log' \
|
||||
--exclude='./cache' \
|
||||
--exclude='./tmp' \
|
||||
--exclude='./sessions' \
|
||||
. > "${TEMP_DIR}/gitea_data.tar.gz"
|
||||
|
||||
if [ ! -s "${TEMP_DIR}/gitea_data.tar.gz" ]; then
|
||||
echo -e "${RED}Erreur: L'archive des données est vide${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Dépôts et données sauvegardés${NC}"
|
||||
|
||||
echo -e "${YELLOW}[3/4] Création de l'archive finale...${NC}"
|
||||
# Créer l'archive finale
|
||||
cd "$BACKUP_DIR"
|
||||
tar czf "${BACKUP_NAME}.tar.gz" "${BACKUP_NAME}/"
|
||||
|
||||
if [ ! -s "${BACKUP_NAME}.tar.gz" ]; then
|
||||
echo -e "${RED}Erreur: L'archive finale est vide${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Supprimer le répertoire temporaire
|
||||
rm -rf "${BACKUP_NAME}"
|
||||
cd - > /dev/null
|
||||
|
||||
BACKUP_SIZE=$(du -h "${BACKUP_DIR}/${BACKUP_NAME}.tar.gz" | cut -f1)
|
||||
echo -e "${GREEN}✓ Archive créée: ${BACKUP_NAME}.tar.gz (${BACKUP_SIZE})${NC}"
|
||||
|
||||
echo -e "${YELLOW}[4/4] Nettoyage des anciennes sauvegardes (>$RETENTION_DAYS jours)...${NC}"
|
||||
# Supprimer les sauvegardes plus anciennes que RETENTION_DAYS
|
||||
find "$BACKUP_DIR" -name "gitea_backup_*.tar.gz" -type f -mtime +$RETENTION_DAYS -delete
|
||||
REMAINING_BACKUPS=$(find "$BACKUP_DIR" -name "gitea_backup_*.tar.gz" -type f | wc -l)
|
||||
echo -e "${GREEN}✓ Sauvegardes restantes: $REMAINING_BACKUPS${NC}"
|
||||
|
||||
echo -e "${GREEN}=== Sauvegarde terminée avec succès ===${NC}"
|
||||
echo "Fichier: ${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
|
||||
echo "Taille: $BACKUP_SIZE"
|
||||
191
scripts/restore.sh
Executable file
191
scripts/restore.sh
Executable file
@@ -0,0 +1,191 @@
|
||||
#!/bin/bash
|
||||
# ============================================
|
||||
# Script de restauration Gitea
|
||||
# ============================================
|
||||
# Ce script restaure une sauvegarde complète de Gitea
|
||||
# ATTENTION: Cette opération est destructive!
|
||||
|
||||
set -e # Arrêter en cas d'erreur
|
||||
|
||||
# Couleurs pour l'affichage
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Vérifier qu'un fichier de sauvegarde a été fourni
|
||||
if [ -z "$1" ]; then
|
||||
echo -e "${RED}Erreur: Aucun fichier de sauvegarde spécifié${NC}"
|
||||
echo "Usage: $0 <fichier_sauvegarde.tar.gz>"
|
||||
echo "Exemple: $0 backups/gitea_backup_20240101_120000.tar.gz"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_FILE="$1"
|
||||
|
||||
# Vérifier que le fichier existe
|
||||
if [ ! -f "$BACKUP_FILE" ]; then
|
||||
echo -e "${RED}Erreur: Le fichier $BACKUP_FILE n'existe pas${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que c'est bien un fichier gzip
|
||||
if ! file "$BACKUP_FILE" | grep -q "gzip compressed"; then
|
||||
echo -e "${RED}Erreur: Le fichier n'est pas une archive gzip valide${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validation du chemin (sécurité contre path traversal)
|
||||
BACKUP_FILE=$(realpath "$BACKUP_FILE")
|
||||
if [[ "$BACKUP_FILE" == *".."* ]]; then
|
||||
echo -e "${RED}Erreur: Chemin invalide (path traversal détecté)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Charger les variables d'environnement
|
||||
if [ -f .env ]; then
|
||||
source .env
|
||||
else
|
||||
echo -e "${RED}Erreur: Fichier .env non trouvé${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que les variables nécessaires sont définies
|
||||
if [ -z "$POSTGRES_DATABASE" ] || [ -z "$POSTGRES_USER" ] || [ -z "$POSTGRES_PASSWORD" ]; then
|
||||
echo -e "${RED}Erreur: Variables PostgreSQL non définies dans .env${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Variables
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
BACKUP_NAME=$(basename "$BACKUP_FILE" .tar.gz)
|
||||
|
||||
# Fonction de nettoyage
|
||||
cleanup() {
|
||||
if [ -d "$TEMP_DIR" ]; then
|
||||
echo -e "${YELLOW}Nettoyage des fichiers temporaires...${NC}"
|
||||
rm -rf "$TEMP_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# Piège pour nettoyer en cas d'erreur ou d'interruption
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo -e "${RED}=== ATTENTION: Restauration de Gitea ===${NC}"
|
||||
echo "Fichier de sauvegarde: $BACKUP_FILE"
|
||||
echo -e "${RED}Cette opération va ÉCRASER toutes les données actuelles!${NC}"
|
||||
echo ""
|
||||
read -p "Êtes-vous sûr de vouloir continuer? (oui/non) " -r
|
||||
if [[ ! $REPLY =~ ^[Oo][Uu][Ii]$ ]]; then
|
||||
echo "Restauration annulée."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}=== Début de la restauration ===${NC}"
|
||||
|
||||
echo -e "${YELLOW}[1/5] Extraction de l'archive...${NC}"
|
||||
tar xzf "$BACKUP_FILE" -C "$TEMP_DIR"
|
||||
|
||||
# Trouver le répertoire de sauvegarde
|
||||
BACKUP_DIR=$(find "$TEMP_DIR" -maxdepth 1 -type d -name "gitea_backup_*" | head -n 1)
|
||||
if [ -z "$BACKUP_DIR" ]; then
|
||||
echo -e "${RED}Erreur: Structure de sauvegarde invalide${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que les fichiers nécessaires existent
|
||||
if [ ! -f "$BACKUP_DIR/database.dump" ] || [ ! -f "$BACKUP_DIR/gitea_data.tar.gz" ]; then
|
||||
echo -e "${RED}Erreur: Fichiers de sauvegarde manquants${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Archive extraite${NC}"
|
||||
|
||||
echo -e "${YELLOW}[2/5] Arrêt des services...${NC}"
|
||||
docker compose down
|
||||
echo -e "${GREEN}✓ Services arrêtés${NC}"
|
||||
|
||||
echo -e "${YELLOW}[3/5] Démarrage de la base de données...${NC}"
|
||||
docker compose up -d db
|
||||
echo "Attente du démarrage de PostgreSQL..."
|
||||
sleep 10
|
||||
|
||||
# Attendre que PostgreSQL soit prêt
|
||||
MAX_TRIES=30
|
||||
COUNTER=0
|
||||
until docker compose exec -T db pg_isready -U "$POSTGRES_USER" > /dev/null 2>&1; do
|
||||
COUNTER=$((COUNTER + 1))
|
||||
if [ $COUNTER -gt $MAX_TRIES ]; then
|
||||
echo -e "${RED}Erreur: PostgreSQL ne démarre pas${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo "En attente de PostgreSQL... ($COUNTER/$MAX_TRIES)"
|
||||
sleep 2
|
||||
done
|
||||
echo -e "${GREEN}✓ PostgreSQL prêt${NC}"
|
||||
|
||||
echo -e "${YELLOW}[4/5] Restauration de la base de données...${NC}"
|
||||
# Supprimer et recréer la base de données
|
||||
export PGPASSWORD="$POSTGRES_PASSWORD"
|
||||
docker compose exec -T db psql -U "$POSTGRES_USER" -d postgres -c "DROP DATABASE IF EXISTS $POSTGRES_DATABASE;"
|
||||
docker compose exec -T db psql -U "$POSTGRES_USER" -d postgres -c "CREATE DATABASE $POSTGRES_DATABASE OWNER $POSTGRES_USER;"
|
||||
|
||||
# Restaurer le dump
|
||||
docker compose exec -T db pg_restore \
|
||||
-U "$POSTGRES_USER" \
|
||||
-d "$POSTGRES_DATABASE" \
|
||||
--clean \
|
||||
--if-exists \
|
||||
--no-owner \
|
||||
--no-acl \
|
||||
< "$BACKUP_DIR/database.dump"
|
||||
|
||||
echo -e "${GREEN}✓ Base de données restaurée${NC}"
|
||||
|
||||
echo -e "${YELLOW}[5/5] Restauration des données Gitea...${NC}"
|
||||
# Démarrer Gitea
|
||||
docker compose up -d gitea redis
|
||||
|
||||
# Attendre que Gitea soit prêt
|
||||
echo "Attente du démarrage de Gitea..."
|
||||
sleep 15
|
||||
|
||||
# Arrêter temporairement Gitea pour la restauration des fichiers
|
||||
docker compose stop gitea
|
||||
|
||||
# Nettoyer les données existantes
|
||||
if [ -d "./data" ]; then
|
||||
echo "Suppression des anciennes données..."
|
||||
rm -rf ./data/*
|
||||
fi
|
||||
|
||||
# Extraire les données depuis l'archive
|
||||
mkdir -p ./data
|
||||
tar xzf "$BACKUP_DIR/gitea_data.tar.gz" -C ./data
|
||||
|
||||
echo -e "${GREEN}✓ Données restaurées${NC}"
|
||||
|
||||
echo -e "${YELLOW}Redémarrage de tous les services...${NC}"
|
||||
docker compose up -d
|
||||
|
||||
# Attendre que les services soient prêts
|
||||
sleep 10
|
||||
MAX_TRIES=30
|
||||
COUNTER=0
|
||||
until docker compose ps | grep -q "gitea.*running"; do
|
||||
COUNTER=$((COUNTER + 1))
|
||||
if [ $COUNTER -gt $MAX_TRIES ]; then
|
||||
echo -e "${YELLOW}Avertissement: Gitea met du temps à démarrer${NC}"
|
||||
break
|
||||
fi
|
||||
echo "En attente de Gitea... ($COUNTER/$MAX_TRIES)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo -e "${GREEN}=== Restauration terminée avec succès ===${NC}"
|
||||
echo "Gitea devrait être accessible sur: http://localhost:3000"
|
||||
echo ""
|
||||
echo "Vérifications recommandées:"
|
||||
echo " - Vérifier l'accès web"
|
||||
echo " - Tester l'authentification"
|
||||
echo " - Vérifier les dépôts"
|
||||
echo " - Consulter les logs: docker compose logs -f gitea"
|
||||
106
scripts/update.sh
Executable file
106
scripts/update.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
# ============================================
|
||||
# Script de mise à jour Gitea
|
||||
# ============================================
|
||||
# Ce script met à jour Gitea de manière sécurisée
|
||||
# avec une sauvegarde automatique avant la mise à jour
|
||||
|
||||
set -e # Arrêter en cas d'erreur
|
||||
|
||||
# Couleurs pour l'affichage
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Charger les variables d'environnement
|
||||
if [ -f .env ]; then
|
||||
source .env
|
||||
else
|
||||
echo -e "${RED}Erreur: Fichier .env non trouvé${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fonction de nettoyage en cas d'erreur
|
||||
cleanup() {
|
||||
echo -e "${YELLOW}Une erreur s'est produite. Vérifiez l'état des services.${NC}"
|
||||
echo "Pour revenir à l'état précédent, utilisez la dernière sauvegarde:"
|
||||
echo " make restore FILE=backups/gitea_backup_*.tar.gz"
|
||||
}
|
||||
|
||||
trap cleanup ERR
|
||||
|
||||
echo -e "${GREEN}=== Mise à jour de Gitea ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Vérifier que les services tournent
|
||||
if ! docker compose ps | grep -q "gitea.*running"; then
|
||||
echo -e "${YELLOW}Avertissement: Gitea ne semble pas être en cours d'exécution${NC}"
|
||||
read -p "Continuer quand même? (oui/non) " -r
|
||||
if [[ ! $REPLY =~ ^[Oo][Uu][Ii]$ ]]; then
|
||||
echo "Mise à jour annulée."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[1/6] Création d'une sauvegarde de sécurité...${NC}"
|
||||
if ! bash scripts/backup.sh; then
|
||||
echo -e "${RED}Erreur: La sauvegarde a échoué. Mise à jour annulée.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Sauvegarde créée${NC}"
|
||||
|
||||
echo -e "${YELLOW}[2/6] Téléchargement des nouvelles images...${NC}"
|
||||
docker compose pull
|
||||
echo -e "${GREEN}✓ Images téléchargées${NC}"
|
||||
|
||||
echo -e "${YELLOW}[3/6] Arrêt des services...${NC}"
|
||||
docker compose down
|
||||
echo -e "${GREEN}✓ Services arrêtés${NC}"
|
||||
|
||||
echo -e "${YELLOW}[4/6] Démarrage avec les nouvelles versions...${NC}"
|
||||
docker compose up -d
|
||||
echo -e "${GREEN}✓ Services démarrés${NC}"
|
||||
|
||||
echo -e "${YELLOW}[5/6] Attente du démarrage complet...${NC}"
|
||||
sleep 10
|
||||
|
||||
# Attendre que Gitea soit prêt
|
||||
MAX_TRIES=60
|
||||
COUNTER=0
|
||||
until docker compose exec -T gitea wget -q --spider http://localhost:3000/api/healthz 2>/dev/null; do
|
||||
COUNTER=$((COUNTER + 1))
|
||||
if [ $COUNTER -gt $MAX_TRIES ]; then
|
||||
echo -e "${RED}Erreur: Gitea ne répond pas après la mise à jour${NC}"
|
||||
echo "Vérifiez les logs: docker compose logs gitea"
|
||||
exit 1
|
||||
fi
|
||||
echo "En attente de Gitea... ($COUNTER/$MAX_TRIES)"
|
||||
sleep 2
|
||||
done
|
||||
echo -e "${GREEN}✓ Gitea répond${NC}"
|
||||
|
||||
echo -e "${YELLOW}[6/6] Vérification de l'état...${NC}"
|
||||
# Afficher les versions
|
||||
echo ""
|
||||
echo "Versions actuelles:"
|
||||
docker compose images
|
||||
|
||||
echo ""
|
||||
echo "État des services:"
|
||||
docker compose ps
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Mise à jour terminée avec succès ===${NC}"
|
||||
echo ""
|
||||
echo "Vérifications recommandées:"
|
||||
echo " 1. Accéder à l'interface web: http://localhost:3000"
|
||||
echo " 2. Vérifier les dépôts existants"
|
||||
echo " 3. Tester les fonctionnalités principales"
|
||||
echo " 4. Consulter les logs: docker compose logs -f gitea"
|
||||
echo ""
|
||||
echo "En cas de problème, restaurez la sauvegarde:"
|
||||
LATEST_BACKUP=$(ls -t backups/gitea_backup_*.tar.gz 2>/dev/null | head -n 1)
|
||||
if [ -n "$LATEST_BACKUP" ]; then
|
||||
echo " make restore FILE=$LATEST_BACKUP"
|
||||
fi
|
||||
Reference in New Issue
Block a user