# 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 ```mermaid flowchart TB subgraph Config["⚙️ Configuration"] CONF["docker-scripts.conf
DOCKER_APP_NAME + HOSTNAME"] end subgraph Core["🛠️ Scripts core"] BACKUP["docker-backup.sh
💾 Backup quotidien"] UPDATE["docker-auto-update.sh
🔄 Mise à jour auto"] RESTORE["restore.sh
♻️ Restauration"] end subgraph Deploy["🚀 Déploiement"] SETUP["setup.sh
Installateur complet"] CRON["install_cron.sh
Gestion crontab"] end subgraph Runtime["⚡ Runtime"] CRONTAB["Crontab
Backup 2h → Update 4h"] DOCKER["Docker Compose
Gitea + MySQL"] end subgraph Storage["💾 Stockage"] LOCAL["Backups locaux
/NFS/BACKUP/..."] REMOTE["Backup distant
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 ``` ```mermaid 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 ```bash # 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 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é ```cron # 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` : ```bash 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) ```bash # 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. ```bash # 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 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 : ```cron # >>> 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. ```bash # 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 ```bash # 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 ```bash # 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 ```bash # Vérifier les logs tail -50 /var/log/gitea-update.log # Tester manuellement bash /opt/docker-scripts/docker-auto-update.sh ``` ### Restauration ```bash # 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 :** ```bash # 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 ```