From 2d04b90b1a7576a31a1e5ee5b2ee64167bc6ee45 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Fri, 26 Jun 2026 16:47:47 -0400 Subject: [PATCH] Refactor project documentation and add `--check` mode Rebrand from "Docker Scripts" to "Docker Stack Template" and restructure the README as a step-by-step guide. Add `--check` option to `setup.sh` for validating system prerequisites with configurable `CMD_DEPEND`. --- README.md | 902 ++++++++++++++++++++++++++------------------ docker-scripts.conf | 5 + setup.sh | 42 ++- 3 files changed, 571 insertions(+), 378 deletions(-) diff --git a/README.md b/README.md index d2d891c..b809db8 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,19 @@ -# Docker Scripts — Auto-Update, Backup, Restore & Déploiement Cron +# Docker Stack Template — 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. +Template **générique et réutilisable** pour la maintenance automatisée d'applications +Docker (Gitea, ou toute autre app MySQL + volumes) : backup quotidien, mise à jour +automatique, restauration et déploiement cron. -> **🔄 Réutilisable** : changez `DOCKER_APP_NAME=monapp` pour adapter à -> n'importe quelle stack Docker (MySQL + volumes). +> **🔄 Changez juste `DOCKER_APP_NAME=monapp`** pour adapter à n'importe quelle +> stack Docker (MySQL + volumes). Voir [Étape 3](#3--configurer-pour-votre-application). --- ## 📂 Structure du projet ``` -gitea-scripts/ ├── setup.sh ← 🚀 Installateur tout-en-un -├── docker-scripts.conf ← ⚙️ Configuration unifiée (DOCKER_APP_NAME) +├── docker-scripts.conf ← ⚙️ Configuration centralisée (DOCKER_APP_NAME, etc.) ├── docker-backup.sh ← 💾 Backup complet (DB + volumes + config) ├── docker-auto-update.sh ← 🔄 Mise à jour automatique ├── restore.sh ← ♻️ Restauration standalone @@ -22,15 +21,532 @@ gitea-scripts/ └── docker-compose.yml ← 🐳 Stack Docker de référence ``` -### Architecture +--- + +## 🚀 Guide étape par étape + +### 1. Télécharger le template + +```bash +# Créer les dossiers standard (FHS) +sudo mkdir -p /opt/docker-scripts /srv/docker +sudo chown -R $USER:$USER /opt/docker-scripts /srv/docker + +# Cloner le dépôt +cd /opt +git clone https://git.dracodev.net/Outils/docker-stack-template.git docker-scripts + +# Vérifier que tout est là +ls -la /opt/docker-scripts/ +``` + +--- + +### 2. Configurer pour votre application + +C'est l'étape clé : **adapter le template à votre application en éditant 3 fichiers**. + +#### 2a. Copier la configuration dans le dossier de votre app + +```bash +# Créer le dossier de votre application +mkdir -p /srv/docker/monapp + +# Copier la configuration template +cp /opt/docker-scripts/docker-scripts.conf /srv/docker/monapp/ + +# Copier et adapter le docker-compose si vous partez de l'exemple +cp /opt/docker-scripts/docker-compose.yml /srv/docker/monapp/ +``` + +#### 2b. Éditer la configuration spécifique à votre app + +```bash +nano /srv/docker/monapp/docker-scripts.conf +``` + +**Valeurs obligatoires à changer :** + +```bash +# ─── Prérequis (liste des commandes à vérifier) ────────────────────────── +CMD_DEPEND="git,docker,curl,tar,gzip,crontab" # 🔧 Adaptez si besoin + +# ─── Identité de l'application ──────────────────────────────────────────── +DOCKER_APP_NAME="monapp" # 🔧 Nom de votre app + +# ─── Image Docker ───────────────────────────────────────────────────────── +IMAGE_NAME="monapp/monapp" # 🔧 Image Docker utilisée +IMAGE_TAG="latest" # Tag (latest, 1.21, etc.) + +# ─── Mots de passe base de données ──────────────────────────────────────── +DB_PASSWORD="votre-mot-de-passe-securise" # 🔧 User MySQL +DB_ROOT_PASSWORD="votre-autre-mot-de-passe" # 🔧 Root MySQL + +# ─── URLs ───────────────────────────────────────────────────────────────── +HEALTH_CHECK_URL="http://localhost:8080" # 🔧 URL de healthcheck +``` + +**Valeurs optionnelles à adapter selon votre environnement :** + +```bash +# Sauvegardes +BACKUP_DIR="/NFS/BACKUP/DOCKER/$(hostname)/monapp" # Emplacement des backups +RETENTION_DAYS="30" # Jours de rétention + +# Backup distant (optionnel) +REMOTE_BACKUP_ENABLED=false +REMOTE_BACKUP_HOST="backup.example.com" +REMOTE_BACKUP_PATH="/backups/monapp" + +# Notifications (optionnel) +ENABLE_NOTIFICATIONS=false +``` + +> **💡 Les scripts chargent automatiquement** la config de l'app si elle existe +> dans `/srv/docker/$DOCKER_APP_NAME/docker-scripts.conf`. Ils utilisent la +> config template de `/opt/docker-scripts/` comme fallback. + +#### 2c. Adapter le docker-compose.yml + +```bash +nano /srv/docker/monapp/docker-compose.yml +``` + +Points à vérifier : +- Les noms de services correspondent à la convention `${DOCKER_APP_NAME}_server` / `${DOCKER_APP_NAME}_db` +- Les chemins de volumes pointent vers `/srv/docker/monapp/data`, `/srv/docker/monapp/mysql`, etc. +- Les **mots de passe** dans `docker-compose.yml` sont cohérents avec ceux de `docker-scripts.conf` +- Les healthchecks sont configurés sur les deux services + +--- + +### 3. Valider les prérequis + +Une fois la configuration faite, vérifiez que votre serveur a tout le nécessaire : + +```bash +# Vérification des prérequis (lit CMD_DEPEND depuis docker-scripts.conf) +bash /opt/docker-scripts/setup.sh --check +``` + +Ce one-liner vérifie automatiquement la présence de chaque commande listée dans +`CMD_DEPEND` (défaut : `git,docker,curl,tar,gzip,crontab`), ainsi que Docker +Compose et le daemon Docker. + +**Prérequis standards et leur installation :** +| Outil | Pourquoi | Installation | +|-------|----------|-------------| +| `git` | Cloner/mettre à jour les scripts | `apt install git` | +| `docker` | Conteneurisation | [docs.docker.com](https://docs.docker.com/engine/install/) | +| `docker compose` | Orchestration | Plugin inclus avec Docker Engine ≥ 24 | +| `curl` | Healthchecks & notifications | `apt install curl` | +| `tar` + `gzip` | Compression des backups | Préinstallé sur la plupart des distribs | +| `crontab` | Planification automatique | `apt install cron` | +| Droits sudo | Accès aux volumes protégés | L'utilisateur doit pouvoir `sudo` | + +> **💡 Ajoutez vos propres prérequis** dans `CMD_DEPEND` (ex : `CMD_DEPEND="git,docker,curl,tar,gzip,crontab,mysqldump"`) +> pour que `--check` les valide aussi. + +--- + +### 4. Installer avec setup.sh + +```bash +# Installation interactive (recommandée la première fois) +bash /opt/docker-scripts/setup.sh + +# Ou forcer sans confirmation +bash /opt/docker-scripts/setup.sh --force + +# Ou prévisualiser ce qui sera fait +bash /opt/docker-scripts/setup.sh --dry-run +``` + +**Ce que `setup.sh` fait automatiquement :** + +```mermaid +flowchart TD + A["🔍 Étape 1 : Vérification prérequis"] --> B["📥 Étape 2 : Clone/màj depuis Git"] + B --> C["🔑 Étape 3 : Permissions d'exécution"] + C --> D["📝 Étape 4 : Configuration des logs"] + D --> E["🔄 Étape 5 : Configuration logrotate"] + E --> F["🕐 Étape 6 : Installation des crons"] + F --> G["💾 Option : Premier backup manuel"] +``` + +> **⚠️ Note :** `setup.sh` installe les crons **depuis le dossier `/opt/docker-scripts/`**. +> Pour pointer vers une app spécifique, créez un fichier `.env` dans le dossier +> de l'app ou passez `DOCKER_APP_NAME=monapp` en variable d'environnement. + +--- + +### 5. Valider l'installation + +#### 5a. Vérifier les crons + +```bash +# Vérifier que les crons sont bien installés +bash /opt/docker-scripts/install_cron.sh --status + +# Ou inspecter directement la crontab +crontab -l | grep -A 3 "DOCKER SCRIPTS" +``` + +Vous devriez voir un bloc similaire à : + +```cron +# >>> MONAPP SCRIPTS (managed by install_cron.sh) <<< +0 2 * * * /opt/docker-scripts/docker-backup.sh >> /var/log/monapp-backup-cron.log 2>&1 +0 4 * * * /opt/docker-scripts/docker-auto-update.sh >> /var/log/monapp-update-cron.log 2>&1 +# >>> END MONAPP SCRIPTS <<< +``` + +#### 5b. Lancer un premier backup manuel + +```bash +# Premier backup réel +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/docker-backup.sh + +# Vérifier le résultat +ls -la /NFS/BACKUP/DOCKER/$(hostname)/monapp/ +``` + +#### 5c. Vérifier les logs + +```bash +# Logs du backup +tail -20 /var/log/monapp-backup.log + +# Logs de l'auto-update +tail -20 /var/log/monapp-update.log + +# Logs cron +tail -20 /var/log/monapp-backup-cron.log +``` + +#### 5d. Tester l'auto-update + +```bash +# Test manuel de la mise à jour automatique +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/docker-auto-update.sh +``` + +#### 5e. Tester la restauration (optionnel mais recommandé) + +```bash +# Lister les backups disponibles +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/restore.sh + +# Dry-run d'une restauration (vérifie sans exécuter) +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/restore.sh \ + /NFS/BACKUP/DOCKER/$(hostname)/monapp/monapp-backup-AAAAMMJJ-HHMMSS --dry-run +``` + +--- + +### 6. Opérations quotidiennes + +Une fois installé, le système tourne **automatiquement** : + +```mermaid +flowchart LR + subgraph Daily["📅 Quotidien automatique (cron)"] + direction TB + A["🕐 2h00 — Backup"] --> B["💾 Sauvegarde complète
(DB + volumes + config)"] + B --> C["🧹 Nettoyage vieux backups"] + C --> D["☁️ Sync distante (si activée)"] + + E["🕐 4h00 — Auto-update"] --> F{"Nouvelle image Docker ?"} + F -->|"Non"| G["✅ Rien à faire"] + F -->|"Oui"| H["💾 Backup DB rapide"] + H --> I["🚀 docker compose up -d"] + I --> J{"Santé OK ?"} + J -->|"Oui"| K["✅ Mise à jour OK"] + J -->|"Non"| L["🔄 Rollback automatique"] + end +``` + +#### Commandes utiles au quotidien + +```bash +# ─── Vérifier l'état ─────────────────────────────────────────────────── +bash /opt/docker-scripts/install_cron.sh --status # État des crons +docker compose -f /srv/docker/monapp/docker-compose.yml ps # État des conteneurs +df -h /NFS/BACKUP/DOCKER/$(hostname)/monapp # Espace disque backups + +# ─── Backup manuel ───────────────────────────────────────────────────── +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/docker-backup.sh + +# ─── Restaurer un backup ─────────────────────────────────────────────── +# Lister les backups +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/restore.sh +# Restaurer le plus récent +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/restore.sh \ + $(ls -td /NFS/BACKUP/DOCKER/$(hostname)/monapp/monapp-backup-* | head -1) + +# ─── Mettre à jour les scripts ───────────────────────────────────────── +bash /opt/docker-scripts/setup.sh --update + +# ─── Désinstaller les crons ──────────────────────────────────────────── +bash /opt/docker-scripts/install_cron.sh --uninstall +``` + +--- + +## ⚙️ Référence de configuration + +### Fichier `docker-scripts.conf` + +Tous les paramètres sont centralisés dans `docker-scripts.conf`. Les scripts +utilisent un système de **surcharge à deux niveaux** : + +1. **Config globale** (`/opt/docker-scripts/docker-scripts.conf`) — valeurs par défaut +2. **Config applicative** (`/srv/docker//docker-scripts.conf`) — surcharge la globale + +Les variables d'environnement **prennent le dessus** sur les deux fichiers. + +```bash +# Exemple : changer le dossier de backup à la volée +BACKUP_DIR=/mnt/big-disk/monapp DOCKER_APP_NAME=monapp bash /opt/docker-scripts/docker-backup.sh + +# Exemple : backup avec arrêt des conteneurs +STOP_CONTAINERS=true DOCKER_APP_NAME=monapp bash /opt/docker-scripts/docker-backup.sh + +# Exemple : backup + sync distante +REMOTE_BACKUP_ENABLED=true DOCKER_APP_NAME=monapp bash /opt/docker-scripts/docker-backup.sh +``` + +### Variables clés + +| Variable | Défaut | Description | +|----------|--------|-------------| +| `CMD_DEPEND` | `git,docker,curl,tar,gzip,crontab` | Liste des prérequis pour `setup.sh --check` | +| `DOCKER_APP_NAME` | `gitea` | **🔧 Principal** — nom de l'application (définit tous les dérivés) | +| `IMAGE_NAME` | `gitea/gitea` | **🔧** Image Docker à déployer | +| `IMAGE_TAG` | `latest` | Tag de l'image | +| `COMPOSE_DIR` | `/srv/docker/$DOCKER_APP_NAME` | Dossier docker-compose | +| `BACKUP_DIR` | `/NFS/BACKUP/DOCKER/$HOSTNAME/$DOCKER_APP_NAME` | Destination backups | +| `DB_NAME` | `$DOCKER_APP_NAME` | Nom base de données | +| `DB_PASSWORD` | `change_me_in_production` | **🔧** Mot de passe user MySQL | +| `DB_ROOT_PASSWORD` | `change_me_in_production` | **🔧** Mot de passe root MySQL | +| `HEALTH_CHECK_URL` | `http://localhost:3000` | **🔧** URL de healthcheck | +| `RETENTION_DAYS` | `30` | Rétention des backups (jours) | +| `CRON_BACKUP_SCHEDULE` | `0 2 * * *` | Horaire backup quotidien | +| `CRON_UPDATE_SCHEDULE` | `0 4 * * *` | Horaire mise à jour quotidienne | + +--- + +## 🛠️ Référence des scripts + +### `setup.sh` — Installation complète + +```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 +``` + +### `docker-backup.sh` — Backup complet + +Sauvegarde tout : DB MySQL + volumes Docker + configuration + script restore. + +```bash +DOCKER_APP_NAME=monapp bash docker-backup.sh +``` + +**Structure d'un backup :** + +``` +/NFS/BACKUP/DOCKER/serveur/monapp/ +└── monapp-backup-20260626-020000/ + ├── monapp-db.sql.gz ← Dump MySQL (compressé) + ├── monapp-data.tar.gz ← Volume /data + ├── monapp-mysql.tar.gz ← Volume MySQL + ├── docker-compose.yml ← Stack Docker + ├── app.ini ← Configuration applicative + ├── restore.sh ← ⭐ Script de restauration automatique + └── backup-info.txt ← Métadonnées +``` + +### `restore.sh` — Restauration standalone + +```bash +# Lister les backups disponibles +DOCKER_APP_NAME=monapp bash restore.sh + +# Restauration interactive +DOCKER_APP_NAME=monapp bash restore.sh /chemin/backup + +# Dry-run (vérifier sans exécuter) +DOCKER_APP_NAME=monapp bash restore.sh /chemin/backup --dry-run + +# Forcée (sans confirmation) +DOCKER_APP_NAME=monapp bash restore.sh /chemin/backup --force +``` + +**Étapes de restauration :** +1. Arrêt des conteneurs existants +2. Création des répertoires cibles +3. Restauration des volumes (MySQL, data) +4. Copie du `docker-compose.yml` et de la config +5. Démarrage des conteneurs +6. Restauration de la base de données + redémarrage final + +### `docker-auto-update.sh` — Mise à jour automatique + +```bash +DOCKER_APP_NAME=monapp bash docker-auto-update.sh +``` + +**Fonctionnement :** +1. Récupère le digest SHA256 de l'image actuelle +2. `docker compose pull` pour la dernière version +3. Si le digest est identique → rien à faire +4. Si différent → backup DB rapide → déploiement → healthcheck → rollback si échec +5. Nettoyage des anciennes images + +**Notifications (optionnel) :** + +```bash +# Telegram +ENABLE_NOTIFICATIONS=true NOTIFY_METHOD=telegram \ + TELEGRAM_BOT_TOKEN=xxx TELEGRAM_CHAT_ID=xxx \ + DOCKER_APP_NAME=monapp bash docker-auto-update.sh + +# ntfy.sh +ENABLE_NOTIFICATIONS=true NOTIFY_METHOD=ntfy \ + NTPY_TOPIC=mon-topic \ + DOCKER_APP_NAME=monapp bash docker-auto-update.sh +``` + +### `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 +bash install_cron.sh --uninstall # Retirer du cron (bloc marqué uniquement) +bash install_cron.sh --status # Vérifier l'état +``` + +--- + +## 🔒 Sécurité + +⚠️ Les mots de passe dans `docker-scripts.conf` et `docker-compose.yml` utilisent +des valeurs par défaut. **Changez-les avant toute mise en production :** + +```bash +# Dans /srv/docker/monapp/docker-scripts.conf +DB_ROOT_PASSWORD=votre-mot-de-passe-securise +DB_PASSWORD=votre-autre-mot-de-passe +``` + +```yaml +# Dans /srv/docker/monapp/docker-compose.yml +environment: + MYSQL_ROOT_PASSWORD: votre-mot-de-passe-securise + MYSQL_PASSWORD: votre-autre-mot-de-passe +``` + +--- + +## 📊 Logs + +| Script | Log | +|--------|-----| +| Backup | `/var/log/-backup.log` | +| Auto-update | `/var/log/-update.log` | +| Cron backup | `/var/log/-backup-cron.log` | +| Cron update | `/var/log/-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/-backup.lock` +- `/tmp/-auto-update.lock` + +Un lock stale (PID inexistant) est automatiquement nettoyé. + +--- + +## 🔧 Dépannage + +### Le backup échoue par manque d'espace + +```bash +# Vérifier l'espace +df -h /NFS/BACKUP/DOCKER/$(hostname)/monapp + +# Nettoyer les vieux backups (garde les 10 plus récents) +ls -t /NFS/BACKUP/DOCKER/$(hostname)/monapp/monapp-backup-* | tail -n +11 | xargs rm -rf +``` + +### L'auto-update échoue + +```bash +# Vérifier les logs +tail -50 /var/log/monapp-update.log + +# Tester manuellement +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/docker-auto-update.sh +``` + +### Les crons ne s'exécutent pas + +```bash +# Vérifier l'état +bash /opt/docker-scripts/install_cron.sh --status + +# Vérifier les logs cron système +grep CRON /var/log/syslog | tail -20 + +# Réinstaller les crons +bash /opt/docker-scripts/install_cron.sh --force +``` + +### Restauration d'urgence + +```bash +# Lister les backups +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/restore.sh + +# Restaurer le plus récent +DOCKER_APP_NAME=monapp bash /opt/docker-scripts/restore.sh \ + $(ls -td /NFS/BACKUP/DOCKER/$(hostname)/monapp/monapp-backup-* | head -1) +``` + +### Mettre à jour les scripts eux-mêmes + +```bash +bash /opt/docker-scripts/setup.sh --update +``` + +> 💡 Pour automatiser la mise à jour des scripts, ajoutez cette ligne à la crontab : +> ```cron +> 0 3 * * 0 bash /opt/docker-scripts/setup.sh --update --force +> ``` + +--- + +## 🏗️ Architecture ```mermaid flowchart TB subgraph Config["⚙️ Configuration"] - CONF["docker-scripts.conf
DOCKER_APP_NAME + HOSTNAME"] + GLOBAL["/opt/docker-scripts/docker-scripts.conf
Template global"] + APP["/srv/docker/monapp/docker-scripts.conf
Config applicative (prioritaire)"] end - subgraph Core["🛠️ Scripts core"] + subgraph Scripts["🛠️ Scripts core"] BACKUP["docker-backup.sh
💾 Backup quotidien"] UPDATE["docker-auto-update.sh
🔄 Mise à jour auto"] RESTORE["restore.sh
♻️ Restauration"] @@ -43,7 +559,7 @@ flowchart TB subgraph Runtime["⚡ Runtime"] CRONTAB["Crontab
Backup 2h → Update 4h"] - DOCKER["Docker Compose
Gitea + MySQL"] + DOCKER["Docker Compose
App + MySQL"] end subgraph Storage["💾 Stockage"] @@ -51,374 +567,16 @@ flowchart TB REMOTE["Backup distant
rsync / SCP"] end - CONF --> BACKUP - CONF --> UPDATE - CONF --> RESTORE - CONF --> CRON - + GLOBAL --> Scripts + APP --> Scripts 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-stack-template.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 -``` diff --git a/docker-scripts.conf b/docker-scripts.conf index afbb819..f66606b 100644 --- a/docker-scripts.conf +++ b/docker-scripts.conf @@ -13,6 +13,11 @@ # DOCKER_APP_NAME=monapp bash docker-backup.sh # ============================================================================= +# ─── Prérequis système ──────────────────────────────────────────────────────── +# Liste des commandes requises (séparées par des virgules). +# setup.sh --check les valide automatiquement. +CMD_DEPEND="${CMD_DEPEND:-git,docker,curl,tar,gzip,crontab}" + # ─── Identité ───────────────────────────────────────────────────────────────── # Hôte : automatiquement détecté, surchargeable HOSTNAME="${HOSTNAME:-$(hostname)}" diff --git a/setup.sh b/setup.sh index 429f3e1..cf2b848 100644 --- a/setup.sh +++ b/setup.sh @@ -47,6 +47,7 @@ usage() { Usage: $0 [OPTIONS] Options : + --check Vérifier les prérequis uniquement (sans installer) --force Installation sans confirmation --update Mettre à jour les scripts existants (git pull) --dry-run Affiche ce qui serait fait sans rien installer @@ -56,19 +57,26 @@ Variables d'environnement : GIT_REPO URL du dépôt Git (défaut: $GIT_REPO) SCRIPTS_DIR Dossier d'installation (défaut: /opt/docker-scripts) BRANCH Branche Git à utiliser (défaut: main) + CMD_DEPEND Liste des prérequis (défaut: git,docker,curl,tar,gzip,crontab) EOF exit 0 } # ─── Vérification des prérequis système ───────────────────────────────────── check_system_prerequisites() { - step "Étape 1/6 : Vérification des prérequis système" + step "Vérification des prérequis système" local missing=0 - info "Vérification des commandes requises..." + # Lire la liste depuis la configuration (défaut: git,docker,curl,tar,gzip,crontab) + CMD_DEPEND="${CMD_DEPEND:-git,docker,curl,tar,gzip,crontab}" + IFS=',' read -ra CMDS <<< "$CMD_DEPEND" - for cmd in git docker curl tar gzip crontab; do + info "Vérification des commandes requises (CMD_DEPEND=$CMD_DEPEND)..." + + for cmd in "${CMDS[@]}"; do + # Trim whitespace + cmd="$(echo "$cmd" | xargs)" if command -v "$cmd" &>/dev/null; then local version="" case "$cmd" in @@ -83,7 +91,7 @@ check_system_prerequisites() { fi done - # Vérifier docker compose + # Vérifier docker compose (toujours pertinent, pas dans CMD_DEPEND) if docker compose version &>/dev/null; then ok "docker compose (plugin)" elif command -v docker-compose &>/dev/null; then @@ -103,7 +111,7 @@ check_system_prerequisites() { if [[ $missing -gt 0 ]]; then echo "" err "$missing prérequis manquants. Installez-les avant de continuer." - exit 1 + return 1 fi return 0 @@ -364,9 +372,11 @@ do_update() { FORCE=false DRY_RUN=false UPDATE=false +CHECK=false for arg in "$@"; do case "$arg" in + --check) CHECK=true ;; --force) FORCE=true ;; --dry-run) DRY_RUN=true ;; --update) UPDATE=true ;; @@ -385,6 +395,26 @@ info "Dépôt Git : $GIT_REPO" info "Branche : $BRANCH" echo "" +# ─── Mode vérification (--check) ──────────────────────────────────────────── +if [[ "$CHECK" == "true" ]]; then + echo "" + echo "🔍 VÉRIFICATION DES PRÉREQUIS" + echo "" + if check_system_prerequisites; then + echo "" + ok "Tous les prérequis sont satisfaits. Vous pouvez lancer l'installation :" + echo "" + echo " bash $0" + echo " bash $0 --force (sans confirmation)" + echo "" + exit 0 + else + echo "" + err "Corrigez les prérequis manquants avant de lancer l'installation." + exit 1 + fi +fi + # ─── Mode mise à jour ────────────────────────────────────────────────────── if [[ "$UPDATE" == "true" ]]; then do_update @@ -396,7 +426,7 @@ if [[ "$DRY_RUN" == "true" ]]; then echo "" echo "Actions qui seraient exécutées :" echo "" - echo " 1. Vérifier les prérequis (git, docker, curl, tar, gzip, crontab)" + echo " 1. Vérifier les prérequis (CMD_DEPEND=${CMD_DEPEND:-git,docker,curl,tar,gzip,crontab})" echo " 2. Cloner/MàJ $GIT_REPO → $SCRIPTS_DIR" echo " 3. Rendre les scripts exécutables" echo " 4. Créer les dossiers de logs"