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`.
This commit is contained in:
@@ -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
|
Template **générique et réutilisable** pour la maintenance automatisée d'applications
|
||||||
Docker (Gitea, ou toute autre app MySQL + volumes) : backup, mise à jour,
|
Docker (Gitea, ou toute autre app MySQL + volumes) : backup quotidien, mise à jour
|
||||||
restauration et déploiement.
|
automatique, restauration et déploiement cron.
|
||||||
|
|
||||||
> **🔄 Réutilisable** : changez `DOCKER_APP_NAME=monapp` pour adapter à
|
> **🔄 Changez juste `DOCKER_APP_NAME=monapp`** pour adapter à n'importe quelle
|
||||||
> n'importe quelle stack Docker (MySQL + volumes).
|
> stack Docker (MySQL + volumes). Voir [Étape 3](#3--configurer-pour-votre-application).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📂 Structure du projet
|
## 📂 Structure du projet
|
||||||
|
|
||||||
```
|
```
|
||||||
gitea-scripts/
|
|
||||||
├── setup.sh ← 🚀 Installateur tout-en-un
|
├── 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-backup.sh ← 💾 Backup complet (DB + volumes + config)
|
||||||
├── docker-auto-update.sh ← 🔄 Mise à jour automatique
|
├── docker-auto-update.sh ← 🔄 Mise à jour automatique
|
||||||
├── restore.sh ← ♻️ Restauration standalone
|
├── restore.sh ← ♻️ Restauration standalone
|
||||||
@@ -22,15 +21,532 @@ gitea-scripts/
|
|||||||
└── docker-compose.yml ← 🐳 Stack Docker de référence
|
└── 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<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
|
||||||
|
|
||||||
|
```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/<app>/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/<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
|
||||||
|
|
||||||
|
```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
|
```mermaid
|
||||||
flowchart TB
|
flowchart TB
|
||||||
subgraph Config["⚙️ Configuration"]
|
subgraph Config["⚙️ Configuration"]
|
||||||
CONF["docker-scripts.conf<br/>DOCKER_APP_NAME + HOSTNAME"]
|
GLOBAL["/opt/docker-scripts/docker-scripts.conf<br/>Template global"]
|
||||||
|
APP["/srv/docker/monapp/docker-scripts.conf<br/>Config applicative (prioritaire)"]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph Core["🛠️ Scripts core"]
|
subgraph Scripts["🛠️ Scripts core"]
|
||||||
BACKUP["docker-backup.sh<br/>💾 Backup quotidien"]
|
BACKUP["docker-backup.sh<br/>💾 Backup quotidien"]
|
||||||
UPDATE["docker-auto-update.sh<br/>🔄 Mise à jour auto"]
|
UPDATE["docker-auto-update.sh<br/>🔄 Mise à jour auto"]
|
||||||
RESTORE["restore.sh<br/>♻️ Restauration"]
|
RESTORE["restore.sh<br/>♻️ Restauration"]
|
||||||
@@ -43,7 +559,7 @@ flowchart TB
|
|||||||
|
|
||||||
subgraph Runtime["⚡ Runtime"]
|
subgraph Runtime["⚡ Runtime"]
|
||||||
CRONTAB["Crontab<br/>Backup 2h → Update 4h"]
|
CRONTAB["Crontab<br/>Backup 2h → Update 4h"]
|
||||||
DOCKER["Docker Compose<br/>Gitea + MySQL"]
|
DOCKER["Docker Compose<br/>App + MySQL"]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph Storage["💾 Stockage"]
|
subgraph Storage["💾 Stockage"]
|
||||||
@@ -51,374 +567,16 @@ flowchart TB
|
|||||||
REMOTE["Backup distant<br/>rsync / SCP"]
|
REMOTE["Backup distant<br/>rsync / SCP"]
|
||||||
end
|
end
|
||||||
|
|
||||||
CONF --> BACKUP
|
GLOBAL --> Scripts
|
||||||
CONF --> UPDATE
|
APP --> Scripts
|
||||||
CONF --> RESTORE
|
|
||||||
CONF --> CRON
|
|
||||||
|
|
||||||
SETUP --> CRON
|
SETUP --> CRON
|
||||||
SETUP --> DOCKER
|
SETUP --> DOCKER
|
||||||
CRON --> CRONTAB
|
CRON --> CRONTAB
|
||||||
CRONTAB --> BACKUP
|
CRONTAB --> BACKUP
|
||||||
CRONTAB --> UPDATE
|
CRONTAB --> UPDATE
|
||||||
|
|
||||||
BACKUP --> LOCAL
|
BACKUP --> LOCAL
|
||||||
BACKUP --> REMOTE
|
BACKUP --> REMOTE
|
||||||
RESTORE --> LOCAL
|
RESTORE --> LOCAL
|
||||||
RESTORE --> DOCKER
|
RESTORE --> DOCKER
|
||||||
UPDATE --> 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
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -13,6 +13,11 @@
|
|||||||
# DOCKER_APP_NAME=monapp bash docker-backup.sh
|
# 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é ─────────────────────────────────────────────────────────────────
|
# ─── Identité ─────────────────────────────────────────────────────────────────
|
||||||
# Hôte : automatiquement détecté, surchargeable
|
# Hôte : automatiquement détecté, surchargeable
|
||||||
HOSTNAME="${HOSTNAME:-$(hostname)}"
|
HOSTNAME="${HOSTNAME:-$(hostname)}"
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ usage() {
|
|||||||
Usage: $0 [OPTIONS]
|
Usage: $0 [OPTIONS]
|
||||||
|
|
||||||
Options :
|
Options :
|
||||||
|
--check Vérifier les prérequis uniquement (sans installer)
|
||||||
--force Installation sans confirmation
|
--force Installation sans confirmation
|
||||||
--update Mettre à jour les scripts existants (git pull)
|
--update Mettre à jour les scripts existants (git pull)
|
||||||
--dry-run Affiche ce qui serait fait sans rien installer
|
--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)
|
GIT_REPO URL du dépôt Git (défaut: $GIT_REPO)
|
||||||
SCRIPTS_DIR Dossier d'installation (défaut: /opt/docker-scripts)
|
SCRIPTS_DIR Dossier d'installation (défaut: /opt/docker-scripts)
|
||||||
BRANCH Branche Git à utiliser (défaut: main)
|
BRANCH Branche Git à utiliser (défaut: main)
|
||||||
|
CMD_DEPEND Liste des prérequis (défaut: git,docker,curl,tar,gzip,crontab)
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# ─── Vérification des prérequis système ─────────────────────────────────────
|
# ─── Vérification des prérequis système ─────────────────────────────────────
|
||||||
check_system_prerequisites() {
|
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
|
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
|
if command -v "$cmd" &>/dev/null; then
|
||||||
local version=""
|
local version=""
|
||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
@@ -83,7 +91,7 @@ check_system_prerequisites() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Vérifier docker compose
|
# Vérifier docker compose (toujours pertinent, pas dans CMD_DEPEND)
|
||||||
if docker compose version &>/dev/null; then
|
if docker compose version &>/dev/null; then
|
||||||
ok "docker compose (plugin)"
|
ok "docker compose (plugin)"
|
||||||
elif command -v docker-compose &>/dev/null; then
|
elif command -v docker-compose &>/dev/null; then
|
||||||
@@ -103,7 +111,7 @@ check_system_prerequisites() {
|
|||||||
if [[ $missing -gt 0 ]]; then
|
if [[ $missing -gt 0 ]]; then
|
||||||
echo ""
|
echo ""
|
||||||
err "$missing prérequis manquants. Installez-les avant de continuer."
|
err "$missing prérequis manquants. Installez-les avant de continuer."
|
||||||
exit 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -364,9 +372,11 @@ do_update() {
|
|||||||
FORCE=false
|
FORCE=false
|
||||||
DRY_RUN=false
|
DRY_RUN=false
|
||||||
UPDATE=false
|
UPDATE=false
|
||||||
|
CHECK=false
|
||||||
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
|
--check) CHECK=true ;;
|
||||||
--force) FORCE=true ;;
|
--force) FORCE=true ;;
|
||||||
--dry-run) DRY_RUN=true ;;
|
--dry-run) DRY_RUN=true ;;
|
||||||
--update) UPDATE=true ;;
|
--update) UPDATE=true ;;
|
||||||
@@ -385,6 +395,26 @@ info "Dépôt Git : $GIT_REPO"
|
|||||||
info "Branche : $BRANCH"
|
info "Branche : $BRANCH"
|
||||||
echo ""
|
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 ──────────────────────────────────────────────────────
|
# ─── Mode mise à jour ──────────────────────────────────────────────────────
|
||||||
if [[ "$UPDATE" == "true" ]]; then
|
if [[ "$UPDATE" == "true" ]]; then
|
||||||
do_update
|
do_update
|
||||||
@@ -396,7 +426,7 @@ if [[ "$DRY_RUN" == "true" ]]; then
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Actions qui seraient exécutées :"
|
echo "Actions qui seraient exécutées :"
|
||||||
echo ""
|
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 " 2. Cloner/MàJ $GIT_REPO → $SCRIPTS_DIR"
|
||||||
echo " 3. Rendre les scripts exécutables"
|
echo " 3. Rendre les scripts exécutables"
|
||||||
echo " 4. Créer les dossiers de logs"
|
echo " 4. Créer les dossiers de logs"
|
||||||
|
|||||||
Reference in New Issue
Block a user