bruno 0fc2b8d0d6 Adopter la structure FHS /srv/docker/ et /opt/docker-scripts/
Changements majeurs :
- SCRIPTS_DIR passe de ~/scripts a /opt/docker-scripts (FHS /opt/)
- COMPOSE_DIR, VOLUME_DATA, VOLUME_MYSQL passes a /srv/docker/ (FHS /srv/)
- Ajout de GIT_REPO et GIT_BRANCH dans docker-scripts.conf
- setup.sh source la config des le debut pour centraliser tous les defauts
- Tous les fallbacks internes des scripts alignes avec la config
- docker-compose.yml de reference mis a jour
- README : nouvelles instructions d'installation et chemins

Avantages : un seul dossier par app Docker, backup/migration simplifies,
structure standard FHS, aucune modif de script necessaire par projet.
2026-06-26 15:22:47 -04:00

Docker Scripts — Auto-Update, Backup, Restore & Déploiement Cron

Solution complète et générique pour la maintenance automatisée d'applications Docker (Gitea, ou toute autre app MySQL + volumes) : backup, mise à jour, restauration et déploiement.

🔄 Réutilisable : changez DOCKER_APP_NAME=monapp pour adapter à n'importe quelle stack Docker (MySQL + volumes).


📂 Structure du projet

gitea-scripts/
├── setup.sh                  ← 🚀 Installateur tout-en-un
├── docker-scripts.conf       ← ⚙️  Configuration unifiée (DOCKER_APP_NAME)
├── docker-backup.sh          ← 💾 Backup complet (DB + volumes + config)
├── docker-auto-update.sh     ← 🔄 Mise à jour automatique
├── restore.sh                ← ♻️  Restauration standalone
├── install_cron.sh           ← 🕐 Gestion des crons
└── docker-compose.yml        ← 🐳 Stack Docker de référence

Architecture

flowchart TB
    subgraph Config["⚙️ Configuration"]
        CONF["docker-scripts.conf<br/>DOCKER_APP_NAME + HOSTNAME"]
    end

    subgraph Core["🛠️ Scripts core"]
        BACKUP["docker-backup.sh<br/>💾 Backup quotidien"]
        UPDATE["docker-auto-update.sh<br/>🔄 Mise à jour auto"]
        RESTORE["restore.sh<br/>♻️ Restauration"]
    end

    subgraph Deploy["🚀 Déploiement"]
        SETUP["setup.sh<br/>Installateur complet"]
        CRON["install_cron.sh<br/>Gestion crontab"]
    end

    subgraph Runtime["⚡ Runtime"]
        CRONTAB["Crontab<br/>Backup 2h → Update 4h"]
        DOCKER["Docker Compose<br/>Gitea + MySQL"]
    end

    subgraph Storage["💾 Stockage"]
        LOCAL["Backups locaux<br/>/NFS/BACKUP/..."]
        REMOTE["Backup distant<br/>rsync / SCP"]
    end

    CONF --> BACKUP
    CONF --> UPDATE
    CONF --> RESTORE
    CONF --> CRON

    SETUP --> CRON
    SETUP --> DOCKER
    CRON --> CRONTAB
    CRONTAB --> BACKUP
    CRONTAB --> UPDATE

    BACKUP --> LOCAL
    BACKUP --> REMOTE
    RESTORE --> LOCAL
    RESTORE --> DOCKER
    UPDATE --> DOCKER
flowchart LR
    subgraph Daily["📅 Quotidien (cron)"]
        direction TB
        A["🕐 2h00"] --> B["docker-backup.sh"]
        B --> C["💾 Backup DB + volumes"]
        C --> D["📝 Génère restore.sh"]
        C --> E["☁️ Sync distante"]
        C --> F["🧹 Nettoie vieux backups"]

        G["🕐 4h00"] --> H["docker-auto-update.sh"]
        H --> I{"Nouvelle image ?"}
        I -->|"Non"| J["✅ Rien à faire"]
        I -->|"Oui"| K["💾 Backup DB rapide"]
        K --> L["🚀 docker compose up -d"]
        L --> M{"Santé OK ?"}
        M -->|"Oui"| N["✅ Mise à jour réussie"]
        M -->|"Non"| O["🔄 Rollback auto"]
    end

    subgraph Manual["🖐️ Manuel"]
        direction TB
        P["setup.sh"] --> Q["Installation complète"]
        R["restore.sh"] --> S["Restauration backup"]
        T["setup.sh --update"] --> U["Màj scripts (git pull)"]
    end

🚀 Installation rapide

# 1. Créer le dossier d'installation (standard FHS)
sudo mkdir -p /opt/docker-scripts /srv/docker
sudo chown -R $USER:$USER /opt/docker-scripts /srv/docker

# 2. Cloner les scripts
cd /opt
git clone https://git.dracodev.net/Outils/docker-generic-scripts.git docker-scripts

# 3. Installer
bash /opt/docker-scripts/setup.sh

# Ou forcer sans confirmation
bash /opt/docker-scripts/setup.sh --force

📋 Prérequis

  • Docker + Docker Compose (plugin ou standalone)
  • git, curl, tar, gzip, crontab
  • mysqldump (dans le conteneur MySQL)
  • Droits d'écriture sur le répertoire de backup
  • Droits sudo si les volumes sont protégés

🛠️ Scripts

🚀 setup.sh — Installation complète

Installateur tout-en-un qui configure l'ensemble du système :

bash setup.sh              # Installation interactive
bash setup.sh --force      # Sans confirmation
bash setup.sh --update     # Mise à jour des scripts (git pull)
bash setup.sh --dry-run    # Aperçu sans rien installer

Étapes exécutées :

  1. Vérification des prérequis système
  2. Clone/mise à jour depuis Git
  3. Permissions d'exécution
  4. Configuration des logs
  5. Configuration logrotate (rotation automatique des logs)
  6. Installation des tâches cron

💾 docker-backup.sh — Backup complet

Sauvegarde complète et portable : DB MySQL + volumes Docker + configuration.

Paramètres configurables

Variable Défaut Description
BACKUP_DIR /NFS/BACKUP/DOCKER/$HOSTNAME/gitea Destination backups
COMPOSE_DIR /srv/docker/gitea Dossier docker-compose
DB_CONTAINER gitea_db Conteneur MySQL
DB_NAME gitea Nom base de données
DB_ROOT_PASSWORD gitea Mot de passe root MySQL
VOLUME_DATA /srv/docker/gitea/data Volume data Gitea
VOLUME_MYSQL /srv/docker/gitea/mysql Volume MySQL
RETENTION_DAYS 30 Rétention jours
RETENTION_WEEKLY 4 Backups dimanche conservés
RETENTION_MONTHLY 6 Backups 1er du mois conservés
COMPRESS true Compression gzip
VERIFY_BACKUP true Vérifier intégrité après backup
STOP_CONTAINERS false Arrêter conteneurs (plus sûr)
REMOTE_BACKUP_ENABLED false Activer backup distant (rsync/SCP)

Cron recommandé

# Tous les jours à 2h du matin
0 2 * * * /home/openclaw/scripts/docker-backup.sh

Structure d'un backup

/NFS/BACKUP/DOCKER/dev-prod/gitea/
└── gitea-backup-20260626-020000/
    ├── gitea-db.sql.gz         ← Dump MySQL (compressé)
    ├── gitea-data.tar.gz       ← Volume /data (repos, config, thèmes)
    ├── gitea-mysql.tar.gz      ← Volume MySQL (fichiers DB bruts)
    ├── docker-compose.yml      ← Stack Docker
    ├── app.ini                 ← Configuration Gitea
    ├── restore.sh              ← ⭐ Script de restauration automatique
    └── backup-info.txt         ← Métadonnées

Backup distant (optionnel)

Configurer dans docker-scripts.conf :

REMOTE_BACKUP_ENABLED=true
REMOTE_BACKUP_METHOD=rsync        # ou scp
REMOTE_BACKUP_HOST=backup.example.com
REMOTE_BACKUP_USER=backup
REMOTE_BACKUP_PATH=/backups/gitea
REMOTE_BACKUP_SSH_KEY=/home/user/.ssh/id_rsa

🔄 docker-auto-update.sh — Mise à jour automatique

Vérifie quotidiennement si une nouvelle image Docker Gitea est disponible.

Paramètres configurables

Variable Défaut Description
COMPOSE_DIR /srv/docker/gitea Dossier du docker-compose
APP_SERVICE gitea_server Nom du service dans compose
IMAGE_NAME gitea/gitea Image Docker
IMAGE_TAG latest Tag (version)
HEALTH_CHECK_URL http://localhost:3000 URL vérification santé
HEALTH_CHECK_TIMEOUT 30 Timeout attente (secondes)
VERSION_ENDPOINT (vide) Endpoint version (ex: /api/v1/version)

Fonctionnement

  1. Récupère le digest SHA256 de l'image actuelle
  2. docker compose pull pour télécharger la dernière version
  3. Compare les digests → si identique, rien à faire
  4. Si différent :
    • Backup rapide de la DB
    • Sauvegarde de l'image actuelle pour rollback
    • docker compose up -d avec la nouvelle image
    • Vérification santé
    • Rollback automatique en cas d'échec
  5. Nettoyage ciblé des anciennes images Gitea

Notifications (optionnel)

# Telegram
ENABLE_NOTIFICATIONS=true NOTIFY_METHOD=telegram \
  TELEGRAM_BOT_TOKEN=xxx TELEGRAM_CHAT_ID=xxx \
  bash docker-auto-update.sh

# ntfy.sh
ENABLE_NOTIFICATIONS=true NOTIFY_METHOD=ntfy \
  NTPY_TOPIC=mon-topic \
  bash docker-auto-update.sh

♻️ restore.sh — Restauration standalone

Restaure un backup Gitea sur n'importe quel hôte Docker.

# Lister les backups disponibles
bash restore.sh

# Restauration interactive
bash restore.sh /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-20260626-020000

# Dry-run (vérifier sans exécuter)
bash restore.sh /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-20260626-020000 --dry-run

# Restauration forcée (sans confirmation)
bash restore.sh /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-20260626-020000 --force

Étapes de restauration :

  1. Arrêt des conteneurs existants
  2. Création des répertoires cibles
  3. Restauration du volume MySQL
  4. Restauration du volume Gitea
  5. Copie du docker-compose.yml et app.ini
  6. Démarrage des conteneurs
  7. Restauration de la base de données + redémarrage final

🕐 install_cron.sh — Gestion des crons

bash install_cron.sh              # Installation interactive
bash install_cron.sh --force      # Sans confirmation
bash install_cron.sh --dry-run    # Aperçu sans rien installer
bash install_cron.sh --uninstall  # Retirer du cron
bash install_cron.sh --status     # Vérifier l'état

Le script gère un bloc marqué dans la crontab :

# >>> GITEA SCRIPTS (managed by install_cron.sh) <<<
0 2 * * * /home/bruno/scripts/docker-backup.sh >> /var/log/gitea-backup-cron.log 2>&1
0 4 * * * /home/bruno/scripts/docker-auto-update.sh >> /var/log/gitea-update-cron.log 2>&1
# >>> END GITEA SCRIPTS <<<

Le --uninstall retire uniquement ce bloc, sans toucher au reste de la crontab.


⚙️ Configuration centralisée

Tous les paramètres sont dans docker-scripts.conf. Les scripts chargent ce fichier automatiquement s'il est présent dans le même répertoire.

Les variables d'environnement surchargent les valeurs du fichier de configuration.

# Exemple : changer le dossier de backup
BACKUP_DIR=/mnt/big-disk/gitea bash docker-backup.sh

# Exemple : backup avec arrêt des conteneurs
STOP_CONTAINERS=true bash docker-backup.sh

# Exemple : backup + sync distante
REMOTE_BACKUP_ENABLED=true bash docker-backup.sh

📊 Logs

Script Log
Auto-update /var/log/gitea-update.log
Backup /var/log/gitea-backup.log
Cron backup ~/gitea-backup-cron.log
Cron update ~/gitea-update-cron.log

La rotation des logs est configurée automatiquement par setup.sh via logrotate (rotation hebdomadaire, 12 semaines de rétention, compression).


🔒 Lock files

Pour éviter les exécutions concurrentes (backup + update simultanés), chaque script utilise un lock file dans /tmp :

  • /tmp/${DOCKER_APP_NAME}-backup.lock
  • /tmp/${DOCKER_APP_NAME}-auto-update.lock

Si un lock stale est détecté (PID inexistant), il est automatiquement nettoyé.


🔄 Mise à jour périodique des scripts

# Mise à jour manuelle
bash /opt/docker-scripts/setup.sh --update

# Ajouter au cron pour mise à jour automatique (optionnel)
# 0 3 * * 0 bash /opt/docker-scripts/setup.sh --update --force

🐳 Docker Compose

Le fichier docker-compose.yml fourni inclut :

  • Healthchecks sur les deux services (MySQL + Gitea)
  • depends_on avec condition: service_healthy pour MySQL
  • Timezone mapping pour les logs horodatés correctement

🔧 Dépannage

Le backup échoue par manque d'espace

# Vérifier l'espace disponible
df -h /NFS/BACKUP/DOCKER/dev-prod/gitea

# Nettoyer les vieux backups manuellement
ls -t /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-* | tail -n +10 | xargs rm -rf

L'auto-update échoue

# Vérifier les logs
tail -50 /var/log/gitea-update.log

# Tester manuellement
bash /opt/docker-scripts/docker-auto-update.sh

Restauration

# Lister les backups disponibles
bash /opt/docker-scripts/restore.sh

# Restaurer le plus récent
bash /opt/docker-scripts/restore.sh $(ls -td /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-* | head -1)

🔐 Sécurité

⚠️ Les mots de passe dans docker-scripts.conf et docker-compose.yml sont des valeurs par défaut. Changez-les avant la mise en production :

# Dans docker-scripts.conf
DB_ROOT_PASSWORD=votre-mot-de-passe-securise
DB_PASSWORD=votre-autre-mot-de-passe

# Dans docker-compose.yml
MYSQL_ROOT_PASSWORD=votre-mot-de-passe-securise
MYSQL_PASSWORD=votre-autre-mot-de-passe
GITEA__database__PASSWD=votre-autre-mot-de-passe
S
Description
Scripts automatisés pour Gitea Docker : auto-update et backup
Readme
221 KiB
Languages
Shell 100%