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"