Adopter la structure FHS /srv/docker/ et /opt/docker-scripts/

Changements majeurs :
- SCRIPTS_DIR passe de ~/scripts a /opt/docker-scripts (FHS /opt/)
- COMPOSE_DIR, VOLUME_DATA, VOLUME_MYSQL passes a /srv/docker/ (FHS /srv/)
- Ajout de GIT_REPO et GIT_BRANCH dans docker-scripts.conf
- setup.sh source la config des le debut pour centraliser tous les defauts
- Tous les fallbacks internes des scripts alignes avec la config
- docker-compose.yml de reference mis a jour
- README : nouvelles instructions d'installation et chemins

Avantages : un seul dossier par app Docker, backup/migration simplifies,
structure standard FHS, aucune modif de script necessaire par projet.
This commit is contained in:
2026-06-26 15:22:47 -04:00
parent 6f761fe8ed
commit 0fc2b8d0d6
8 changed files with 74 additions and 50 deletions
+20 -15
View File
@@ -102,14 +102,19 @@ flowchart LR
## 🚀 Installation rapide
```bash
# Cloner et installer en une commande
mkdir ~/git/outils/
cd ~/git/outils/
git clone https://git.dracodev.net/Outils/gitea-scripts.git ~/scripts
bash ~/scripts/setup.sh
# 1. Créer le dossier d'installation (standard FHS)
sudo mkdir -p /opt/docker-scripts /srv/docker
sudo chown -R $USER:$USER /opt/docker-scripts /srv/docker
# 2. Cloner les scripts
cd /opt
git clone https://git.dracodev.net/Outils/docker-generic-scripts.git docker-scripts
# 3. Installer
bash /opt/docker-scripts/setup.sh
# Ou forcer sans confirmation
bash ~/scripts/setup.sh --force
bash /opt/docker-scripts/setup.sh --force
```
---
@@ -156,12 +161,12 @@ Sauvegarde complète et portable : DB MySQL + volumes Docker + configuration.
| Variable | Défaut | Description |
|----------|--------|-------------|
| `BACKUP_DIR` | `/NFS/BACKUP/DOCKER/$HOSTNAME/gitea` | Destination backups |
| `COMPOSE_DIR` | `~/dev/git/outils/gitea` | Dossier docker-compose |
| `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` | `/DOCKER_CONFIG/gitea/data` | Volume data Gitea |
| `VOLUME_MYSQL` | `/DOCKER_CONFIG/gitea/mysql` | Volume 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 |
@@ -214,7 +219,7 @@ Vérifie quotidiennement si une nouvelle image Docker Gitea est disponible.
| Variable | Défaut | Description |
|----------|--------|-------------|
| `COMPOSE_DIR` | `~/dev/git/outils/docker/gitea` | Dossier du docker-compose |
| `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) |
@@ -354,10 +359,10 @@ Si un lock stale est détecté (PID inexistant), il est automatiquement nettoyé
```bash
# Mise à jour manuelle
bash ~/scripts/setup.sh --update
bash /opt/docker-scripts/setup.sh --update
# Ajouter au cron pour mise à jour automatique (optionnel)
# 0 3 * * 0 bash ~/scripts/setup.sh --update --force
# 0 3 * * 0 bash /opt/docker-scripts/setup.sh --update --force
```
---
@@ -388,16 +393,16 @@ ls -t /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-* | tail -n +10 | xargs rm
tail -50 /var/log/gitea-update.log
# Tester manuellement
bash ~/scripts/docker-auto-update.sh
bash /opt/docker-scripts/docker-auto-update.sh
```
### Restauration
```bash
# Lister les backups disponibles
bash ~/scripts/restore.sh
bash /opt/docker-scripts/restore.sh
# Restaurer le plus récent
bash ~/scripts/restore.sh $(ls -td /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-* | head -1)
bash /opt/docker-scripts/restore.sh $(ls -td /NFS/BACKUP/DOCKER/dev-prod/gitea/gitea-backup-* | head -1)
```
---
+1 -1
View File
@@ -24,7 +24,7 @@ fi
DOCKER_APP_NAME="${DOCKER_APP_NAME:-gitea}"
# ─── Configuration locale (après chargement conf, permet surcharge env) ──────
COMPOSE_DIR="${COMPOSE_DIR:-$HOME/dev/git/outils/$DOCKER_APP_NAME}"
COMPOSE_DIR="${COMPOSE_DIR:-/srv/docker/$DOCKER_APP_NAME}"
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
APP_SERVICE="${APP_SERVICE:-${DOCKER_APP_NAME}_server}"
APP_CONTAINER="${APP_CONTAINER:-${DOCKER_APP_NAME}_server}"
+5 -5
View File
@@ -47,8 +47,8 @@ DB_PASSWORD="${DB_PASSWORD:-chab30}"
DB_ROOT_PASSWORD="${DB_ROOT_PASSWORD:-$DOCKER_APP_NAME}"
# Volumes Docker - chemins HÔTE (dérivés de DOCKER_APP_NAME)
VOLUME_DATA="${VOLUME_DATA:-/DOCKER_CONFIG/$DOCKER_APP_NAME/data}"
VOLUME_MYSQL="${VOLUME_MYSQL:-/DOCKER_CONFIG/$DOCKER_APP_NAME/mysql}"
VOLUME_DATA="${VOLUME_DATA:-/srv/docker/$DOCKER_APP_NAME/data}"
VOLUME_MYSQL="${VOLUME_MYSQL:-/srv/docker/$DOCKER_APP_NAME/mysql}"
# Rétention
RETENTION_DAYS="${RETENTION_DAYS:-30}"
@@ -379,9 +379,9 @@ set -euo pipefail
# ─── Configuration cible ────────────────────────────────────────────────────
DOCKER_APP_NAME="${DOCKER_APP_NAME:-__DOCKER_APP_NAME__}"
TARGET_COMPOSE_DIR="${TARGET_COMPOSE_DIR:-$HOME/dev/git/outils/$DOCKER_APP_NAME}"
TARGET_VOLUME_DATA="${TARGET_VOLUME_DATA:-/DOCKER_CONFIG/$DOCKER_APP_NAME/data}"
TARGET_VOLUME_MYSQL="${TARGET_VOLUME_MYSQL:-/DOCKER_CONFIG/$DOCKER_APP_NAME/mysql}"
TARGET_COMPOSE_DIR="${TARGET_COMPOSE_DIR:-/srv/docker/$DOCKER_APP_NAME}"
TARGET_VOLUME_DATA="${TARGET_VOLUME_DATA:-/srv/docker/$DOCKER_APP_NAME/data}"
TARGET_VOLUME_MYSQL="${TARGET_VOLUME_MYSQL:-/srv/docker/$DOCKER_APP_NAME/mysql}"
DB_ROOT_PASSWORD="${DB_ROOT_PASSWORD:-$DOCKER_APP_NAME}"
DB_NAME="${DB_NAME:-$DOCKER_APP_NAME}"
DB_USER="${DB_USER:-$DOCKER_APP_NAME}"
+3 -3
View File
@@ -20,8 +20,8 @@ services:
networks:
- gitea
volumes:
- /DOCKER_CONFIG/gitea/data:/data
- /DOCKER_CONFIG/gitea/data/themes:/data/gitea/public/assets/css/themes
- /srv/docker/gitea/data:/data
- /srv/docker/gitea/data/themes:/data/gitea/public/assets/css/themes
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
@@ -49,7 +49,7 @@ services:
networks:
- gitea
volumes:
- /DOCKER_CONFIG/gitea/mysql:/var/lib/mysql
- /srv/docker/gitea/mysql:/var/lib/mysql
healthcheck:
test:
[
+11 -4
View File
@@ -12,12 +12,18 @@
# Hôte : automatiquement détecté, surchargeable
HOSTNAME="${HOSTNAME:-$(hostname)}"
# Dépôt Git source (utilisé par setup.sh pour clone/mise à jour)
GIT_REPO="${GIT_REPO:-https://git.dracodev.net/Outils/docker-generic-scripts.git}"
GIT_BRANCH="${GIT_BRANCH:-main}"
# Nom de l'application Docker (définit tous les dérivés)
DOCKER_APP_NAME="${DOCKER_APP_NAME:-gitea}"
# ─── Chemins (dérivés de DOCKER_APP_NAME et HOSTNAME) ─────────────────────────
SCRIPTS_DIR="${SCRIPTS_DIR:-$HOME/scripts}"
COMPOSE_DIR="${COMPOSE_DIR:-$HOME/dev/git/outils/$DOCKER_APP_NAME}"
# Dossier d'installation des scripts (standard FHS : /opt/ pour logiciels add-on)
SCRIPTS_DIR="${SCRIPTS_DIR:-/opt/docker-scripts}"
# Dossier de l'application Docker (standard FHS : /srv/ pour données de services)
COMPOSE_DIR="${COMPOSE_DIR:-/srv/docker/$DOCKER_APP_NAME}"
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
BACKUP_DIR="${BACKUP_DIR:-/NFS/BACKUP/DOCKER/$HOSTNAME/$DOCKER_APP_NAME}"
LOCK_DIR="${LOCK_DIR:-/tmp}"
@@ -39,8 +45,9 @@ DB_PASSWORD="${DB_PASSWORD:-chab30}"
DB_ROOT_PASSWORD="${DB_ROOT_PASSWORD:-gitea}"
# ─── Volumes Docker - chemins HÔTE (dérivés de DOCKER_APP_NAME) ───────────────
VOLUME_DATA="${VOLUME_DATA:-/DOCKER_CONFIG/$DOCKER_APP_NAME/data}"
VOLUME_MYSQL="${VOLUME_MYSQL:-/DOCKER_CONFIG/$DOCKER_APP_NAME/mysql}"
# Co-localisés dans /srv/docker/ pour faciliter backup et migration
VOLUME_DATA="${VOLUME_DATA:-/srv/docker/$DOCKER_APP_NAME/data}"
VOLUME_MYSQL="${VOLUME_MYSQL:-/srv/docker/$DOCKER_APP_NAME/mysql}"
# ─── URLs ─────────────────────────────────────────────────────────────────────
HEALTH_CHECK_URL="${HEALTH_CHECK_URL:-http://localhost:3000}"
+3 -3
View File
@@ -26,7 +26,7 @@ fi
DOCKER_APP_NAME="${DOCKER_APP_NAME:-gitea}"
# ─── Configuration locale ────────────────────────────────────────────────────
SCRIPTS_DIR="${SCRIPTS_DIR:-$HOME/scripts}"
SCRIPTS_DIR="${SCRIPTS_DIR:-/opt/docker-scripts}"
CRON_BACKUP_SCHEDULE="${CRON_BACKUP_SCHEDULE:-0 2 * * *}"
CRON_UPDATE_SCHEDULE="${CRON_UPDATE_SCHEDULE:-0 4 * * *}"
BACKUP_SCRIPT="${BACKUP_SCRIPT:-docker-backup.sh}"
@@ -60,7 +60,7 @@ Options :
--help Ce message
Configuration (variables d'environnement) :
SCRIPTS_DIR Dossier des scripts (défaut: \$HOME/scripts)
SCRIPTS_DIR Dossier des scripts (défaut: /opt/docker-scripts)
CRON_BACKUP_SCHEDULE Horaire backup (défaut: 0 2 * * *)
CRON_UPDATE_SCHEDULE Horaire update (défaut: 0 4 * * *)
EOF
@@ -211,7 +211,7 @@ do_install() {
echo ""
err "Prérequis manquants. Placez les scripts dans $SCRIPTS_DIR/"
echo ""
echo " git clone https://git.dracodev.net/Outils/docker-scripts.git $SCRIPTS_DIR"
echo " git clone https://git.dracodev.net/Outils/docker-generic-scripts.git $SCRIPTS_DIR"
echo ""
exit 1
}
+6 -6
View File
@@ -46,9 +46,9 @@ Options :
--help Cette aide
Variables d'environnement :
TARGET_COMPOSE_DIR Dossier docker-compose cible (défaut: ~/dev/git/outils/docker/\${DOCKER_APP_NAME})
TARGET_VOLUME_DATA Volume data cible (défaut: /DOCKER_CONFIG/\${DOCKER_APP_NAME}/data)
TARGET_VOLUME_MYSQL Volume MySQL cible (défaut: /DOCKER_CONFIG/\${DOCKER_APP_NAME}/mysql)
TARGET_COMPOSE_DIR Dossier docker-compose cible (défaut: /srv/docker/\${DOCKER_APP_NAME})
TARGET_VOLUME_DATA Volume data cible (défaut: /srv/docker/\${DOCKER_APP_NAME}/data)
TARGET_VOLUME_MYSQL Volume MySQL cible (défaut: /srv/docker/\${DOCKER_APP_NAME}/mysql)
DB_ROOT_PASSWORD Mot de passe root MySQL (défaut: \${DOCKER_APP_NAME})
DB_NAME Nom base de données (défaut: \${DOCKER_APP_NAME})
EOF
@@ -199,9 +199,9 @@ echo "════════════════════════
echo ""
# ─── Configuration cible ────────────────────────────────────────────────────
TARGET_COMPOSE_DIR="${TARGET_COMPOSE_DIR:-$HOME/dev/git/outils/docker/$DOCKER_APP_NAME}"
TARGET_VOLUME_DATA="${TARGET_VOLUME_DATA:-/DOCKER_CONFIG/$DOCKER_APP_NAME/data}"
TARGET_VOLUME_MYSQL="${TARGET_VOLUME_MYSQL:-/DOCKER_CONFIG/$DOCKER_APP_NAME/mysql}"
TARGET_COMPOSE_DIR="${TARGET_COMPOSE_DIR:-/srv/docker/$DOCKER_APP_NAME}"
TARGET_VOLUME_DATA="${TARGET_VOLUME_DATA:-/srv/docker/$DOCKER_APP_NAME/data}"
TARGET_VOLUME_MYSQL="${TARGET_VOLUME_MYSQL:-/srv/docker/$DOCKER_APP_NAME/mysql}"
DB_ROOT_PASSWORD="${DB_ROOT_PASSWORD:-$DOCKER_APP_NAME}"
DB_NAME="${DB_NAME:-$DOCKER_APP_NAME}"
DB_USER="${DB_USER:-$DOCKER_APP_NAME}"
+25 -13
View File
@@ -20,6 +20,13 @@
set -euo pipefail
# ─── Charger la configuration si présente (permet de centraliser tous les défauts) ─
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [[ -f "$SCRIPT_DIR/docker-scripts.conf" ]]; then
# shellcheck source=/dev/null
source "$SCRIPT_DIR/docker-scripts.conf"
fi
# ─── Couleurs ───────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; BLUE='\033[0;34m'; NC='\033[0m'
ok() { echo -e " ${GREEN}✅${NC} $1"; }
@@ -28,10 +35,10 @@ err() { echo -e " ${RED}❌${NC} $1"; }
info() { echo -e " ${CYAN}📋${NC} $1"; }
step() { echo -e "\n${BLUE}════════════════════════════════════════════════════════${NC}"; echo -e "${BLUE}🔧 $1${NC}"; echo -e "${BLUE}════════════════════════════════════════════════════════${NC}"; }
# ─── Configuration ──────────────────────────────────────────────────────────
GIT_REPO="${GIT_REPO:-https://git.dracodev.net/Outils/docker-scripts.git}"
SCRIPTS_DIR="${SCRIPTS_DIR:-$HOME/scripts}"
BRANCH="${BRANCH:-main}"
# ─── Configuration (fallbacks après chargement de la config) ──────────────────
GIT_REPO="${GIT_REPO:-https://git.dracodev.net/Outils/docker-generic-scripts.git}"
SCRIPTS_DIR="${SCRIPTS_DIR:-/opt/docker-scripts}"
BRANCH="${GIT_BRANCH:-main}"
DOCKER_APP_NAME="${DOCKER_APP_NAME:-gitea}"
# ─── Usage ──────────────────────────────────────────────────────────────────
@@ -47,7 +54,7 @@ Options :
Variables d'environnement :
GIT_REPO URL du dépôt Git (défaut: $GIT_REPO)
SCRIPTS_DIR Dossier d'installation (défaut: \$HOME/scripts)
SCRIPTS_DIR Dossier d'installation (défaut: /opt/docker-scripts)
BRANCH Branche Git à utiliser (défaut: main)
EOF
exit 0
@@ -177,27 +184,32 @@ make_executable() {
setup_logs() {
step "Étape 4/6 : Configuration des logs"
# Charger la config pour connaître LOG_DIR
if [[ -f "$SCRIPTS_DIR/docker-scripts.conf" ]]; then
source "$SCRIPTS_DIR/docker-scripts.conf"
fi
# LOG_DIR, BACKUP_CRON_LOG, UPDATE_CRON_LOG déjà chargés depuis docker-scripts.conf
LOG_DIR="${LOG_DIR:-/var/log}"
BACKUP_CRON_LOG="${BACKUP_CRON_LOG:-$LOG_DIR/${DOCKER_APP_NAME}-backup-cron.log}"
UPDATE_CRON_LOG="${UPDATE_CRON_LOG:-$LOG_DIR/${DOCKER_APP_NAME}-update-cron.log}"
if [[ -d "$LOG_DIR" ]] && [[ -w "$LOG_DIR" ]]; then
ok "Dossier de logs $LOG_DIR accessible"
elif [[ -d "$LOG_DIR" ]]; then
warn "Pas de droit d'écriture sur $LOG_DIR"
info "Les logs seront écrits dans $HOME/"
LOG_DIR="$HOME"
BACKUP_CRON_LOG="$HOME/${DOCKER_APP_NAME}-backup-cron.log"
UPDATE_CRON_LOG="$HOME/${DOCKER_APP_NAME}-update-cron.log"
else
if mkdir -p "$LOG_DIR" 2>/dev/null; then
ok "Dossier de logs $LOG_DIR créé"
else
warn "Impossible de créer $LOG_DIR — logs dans $HOME/"
LOG_DIR="$HOME"
BACKUP_CRON_LOG="$HOME/${DOCKER_APP_NAME}-backup-cron.log"
UPDATE_CRON_LOG="$HOME/${DOCKER_APP_NAME}-update-cron.log"
fi
fi
# Créer les fichiers de log s'ils n'existent pas
touch "$HOME/${DOCKER_APP_NAME}-backup-cron.log" "$HOME/${DOCKER_APP_NAME}-update-cron.log" 2>/dev/null || true
touch "$BACKUP_CRON_LOG" "$UPDATE_CRON_LOG" 2>/dev/null || true
return 0
}
@@ -218,7 +230,7 @@ setup_logrotate() {
need_sudo=true
fi
local log_files="$HOME/${DOCKER_APP_NAME}-backup-cron.log $HOME/${DOCKER_APP_NAME}-update-cron.log /var/log/${DOCKER_APP_NAME}-backup.log /var/log/${DOCKER_APP_NAME}-update.log"
local log_files="$BACKUP_CRON_LOG $UPDATE_CRON_LOG /var/log/${DOCKER_APP_NAME}-backup.log /var/log/${DOCKER_APP_NAME}-update.log"
cat << LOGROTATE
# Rotation des logs Docker scripts
@@ -444,8 +456,8 @@ echo ""
echo "📊 Logs :"
echo " Backup : ${LOG_DIR:-/var/log}/${DOCKER_APP_NAME}-backup.log"
echo " Update : ${LOG_DIR:-/var/log}/${DOCKER_APP_NAME}-update.log"
echo " Cron backup : $HOME/${DOCKER_APP_NAME}-backup-cron.log"
echo " Cron update : $HOME/${DOCKER_APP_NAME}-update-cron.log"
echo " Cron backup : ${BACKUP_CRON_LOG:-$HOME/${DOCKER_APP_NAME}-backup-cron.log}"
echo " Cron update : ${UPDATE_CRON_LOG:-$HOME/${DOCKER_APP_NAME}-update-cron.log}"
echo ""
echo "🕐 Tâches cron :"
echo " Backup : $(grep "$SCRIPTS_DIR/docker-backup.sh" <(crontab -l 2>/dev/null) | awk '{print $1" "$2" "$3" "$4" "$5}')"