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`.
19 KiB
Docker Stack Template — Auto-Update, Backup, Restore & Déploiement Cron
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.
🔄 Changez juste
DOCKER_APP_NAME=monapppour adapter à n'importe quelle stack Docker (MySQL + volumes). Voir Étape 3.
📂 Structure du projet
├── setup.sh ← 🚀 Installateur tout-en-un
├── 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
├── install_cron.sh ← 🕐 Gestion des crons
└── docker-compose.yml ← 🐳 Stack Docker de référence
🚀 Guide étape par étape
1. Télécharger le template
# 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
# 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
nano /srv/docker/monapp/docker-scripts.conf
Valeurs obligatoires à changer :
# ─── 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 :
# 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
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.ymlsont cohérents avec ceux dedocker-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 :
# 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 |
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--checkles valide aussi.
4. Installer avec setup.sh
# 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 :
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.shinstalle les crons depuis le dossier/opt/docker-scripts/. Pour pointer vers une app spécifique, créez un fichier.envdans le dossier de l'app ou passezDOCKER_APP_NAME=monappen variable d'environnement.
5. Valider l'installation
5a. Vérifier les crons
# 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 à :
# >>> 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
# 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
# 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
# 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é)
# 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 :
flowchart LR
subgraph Daily["📅 Quotidien automatique (cron)"]
direction TB
A["🕐 2h00 — Backup"] --> B["💾 Sauvegarde complète<br/>(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
# ─── 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 :
- Config globale (
/opt/docker-scripts/docker-scripts.conf) — valeurs par défaut - Config applicative (
/srv/docker/<app>/docker-scripts.conf) — surcharge la globale
Les variables d'environnement prennent le dessus sur les deux fichiers.
# 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 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.
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
# 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 :
- Arrêt des conteneurs existants
- Création des répertoires cibles
- Restauration des volumes (MySQL, data)
- Copie du
docker-compose.ymlet de la config - Démarrage des conteneurs
- Restauration de la base de données + redémarrage final
docker-auto-update.sh — Mise à jour automatique
DOCKER_APP_NAME=monapp bash docker-auto-update.sh
Fonctionnement :
- Récupère le digest SHA256 de l'image actuelle
docker compose pullpour la dernière version- Si le digest est identique → rien à faire
- Si différent → backup DB rapide → déploiement → healthcheck → rollback si échec
- Nettoyage des anciennes images
Notifications (optionnel) :
# 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 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 :
# Dans /srv/docker/monapp/docker-scripts.conf
DB_ROOT_PASSWORD=votre-mot-de-passe-securise
DB_PASSWORD=votre-autre-mot-de-passe
# 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/<app>-backup.log |
| Auto-update | /var/log/<app>-update.log |
| Cron backup | /var/log/<app>-backup-cron.log |
| Cron update | /var/log/<app>-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/<app>-backup.lock/tmp/<app>-auto-update.lock
Un lock stale (PID inexistant) est automatiquement nettoyé.
🔧 Dépannage
Le backup échoue par manque d'espace
# 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
# 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
# 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
# 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 /opt/docker-scripts/setup.sh --update
💡 Pour automatiser la mise à jour des scripts, ajoutez cette ligne à la crontab :
0 3 * * 0 bash /opt/docker-scripts/setup.sh --update --force
🏗️ Architecture
flowchart TB
subgraph Config["⚙️ Configuration"]
GLOBAL["/opt/docker-scripts/docker-scripts.conf<br/>Template global"]
APP["/srv/docker/monapp/docker-scripts.conf<br/>Config applicative (prioritaire)"]
end
subgraph Scripts["🛠️ 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/>App + MySQL"]
end
subgraph Storage["💾 Stockage"]
LOCAL["Backups locaux<br/>/NFS/BACKUP/..."]
REMOTE["Backup distant<br/>rsync / SCP"]
end
GLOBAL --> Scripts
APP --> Scripts
SETUP --> CRON
SETUP --> DOCKER
CRON --> CRONTAB
CRONTAB --> BACKUP
CRONTAB --> UPDATE
BACKUP --> LOCAL
BACKUP --> REMOTE
RESTORE --> LOCAL
RESTORE --> DOCKER
UPDATE --> DOCKER