Compare commits
45 Commits
7c6a42587c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc1cac8e5a | ||
|
|
5d610b9177 | ||
|
|
8096d8985b | ||
|
|
8462b10e3b | ||
|
|
6bdd8e918c | ||
|
|
44ec0a004a | ||
|
|
c403419ea1 | ||
|
|
a1b51599c6 | ||
|
|
123f7b6a9c | ||
|
|
f02c9b36b2 | ||
|
|
43517b36cc | ||
|
|
57db8b6111 | ||
|
|
53cc23e153 | ||
|
|
a83426d198 | ||
|
|
6fa7704c13 | ||
|
|
b802c8a5cd | ||
|
|
b3ae8a8622 | ||
|
|
7dcffd2ae0 | ||
|
|
08fdfc3a2e | ||
|
|
51d42c6437 | ||
|
|
bd1e2dca27 | ||
|
|
e055d708a5 | ||
|
|
a7c14f9000 | ||
|
|
01c0db45f5 | ||
|
|
b693ed1364 | ||
|
|
dd27bdebb5 | ||
|
|
fcc60226ca | ||
|
|
fb2a3585d4 | ||
|
|
2ed5314537 | ||
|
|
85ed35923c | ||
|
|
f3c74de015 | ||
|
|
58bc9a47cc | ||
|
|
c6de550329 | ||
|
|
701513ce15 | ||
|
|
256d2632a1 | ||
|
|
03821b5e18 | ||
|
|
b9c6122d4f | ||
|
|
f3655144a7 | ||
|
|
386f731c2b | ||
|
|
2dc57afab4 | ||
|
|
517e337a25 | ||
|
|
dc15b4665d | ||
|
|
a7e6cf402d | ||
|
|
db65cd7ec9 | ||
|
|
764b78a12e |
17
.dockerignore
Normal file
17
.dockerignore
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Données Nextcloud
|
||||||
|
data/
|
||||||
|
db/
|
||||||
|
backups/
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
docker-compose*.yml
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
README.md
|
||||||
|
*.md
|
||||||
48
.env.example
48
.env.example
@@ -1,10 +1,44 @@
|
|||||||
MYSQL_DATABASE=
|
# ============================================
|
||||||
MYSQL_ROOT_USER=
|
# MODE: dev | prod
|
||||||
MYSQL_ROOT_PASSWORD=
|
# ============================================
|
||||||
MYSQL_USER=
|
# Copiez ce fichier vers .env et changez les valeurs
|
||||||
MYSQL_PASSWORD=
|
|
||||||
|
|
||||||
NEXTCLOUD_DOMAIN=
|
# Base de données
|
||||||
|
# IMPORTANT: Utilisez des mots de passe forts (min 32 caractères aléatoires)
|
||||||
|
# Générez avec: openssl rand -base64 32
|
||||||
|
MYSQL_DATABASE=nextcloud
|
||||||
|
MYSQL_ROOT_USER=root
|
||||||
|
MYSQL_ROOT_PASSWORD=CHANGEME_GENERATE_STRONG_PASSWORD
|
||||||
|
MYSQL_USER=nextcloud_user
|
||||||
|
MYSQL_PASSWORD=CHANGEME_GENERATE_STRONG_PASSWORD
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
# IMPORTANT: Utilisez un mot de passe fort
|
||||||
|
REDIS_HOST_PASSWORD=CHANGEME_GENERATE_STRONG_PASSWORD
|
||||||
|
|
||||||
|
# Backups
|
||||||
|
BACKUP_DESTINATION=./backups
|
||||||
|
BACKUP_RETENTION_DAYS=7
|
||||||
|
|
||||||
|
# Docker Compose
|
||||||
|
# Le nom du projet est auto-détecté depuis le nom du dossier
|
||||||
|
# Vous pouvez le surcharger ici si nécessaire:
|
||||||
|
# COMPOSE_PROJECT_NAME=mon-nextcloud
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# DÉVELOPPEMENT (localhost)
|
||||||
|
# ============================================
|
||||||
|
NEXTCLOUD_DOMAIN=localhost:8888
|
||||||
TRUSTED_PROXIES=
|
TRUSTED_PROXIES=
|
||||||
|
OVERWRITE_PROTOCOL=http
|
||||||
|
OVERWRITE_HOST=
|
||||||
|
OVERWRITE_CLI_URL=
|
||||||
|
|
||||||
REDIS_HOST_PASSWORD=
|
# ============================================
|
||||||
|
# PRODUCTION (avec Traefik et SSL)
|
||||||
|
# ============================================
|
||||||
|
#NEXTCLOUD_DOMAIN=domain.tld
|
||||||
|
#TRUSTED_PROXIES=172.16.0.0/12
|
||||||
|
#OVERWRITE_PROTOCOL=https
|
||||||
|
#OVERWRITE_HOST=domain.tld
|
||||||
|
#OVERWRITE_CLI_URL=https://domain.tld
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
.env
|
.env
|
||||||
data/
|
data/
|
||||||
db/
|
db/
|
||||||
|
backups/
|
||||||
|
logs/
|
||||||
|
|||||||
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FROM nextcloud:latest
|
||||||
|
|
||||||
|
# Installer ffmpeg pour les previews vidéo
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ffmpeg \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
159
Makefile
159
Makefile
@@ -1,46 +1,157 @@
|
|||||||
.PHONY: help up down restart logs ps occ backup restore update health
|
.PHONY: help up down restart logs logs-all ps shell db-shell redis-shell occ backup restore update health check-health recover clean permissions cron-logs cron-status
|
||||||
|
|
||||||
|
include .env
|
||||||
|
export
|
||||||
|
|
||||||
|
# Detect Docker Compose command
|
||||||
|
DOCKER_COMPOSE := $(shell command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose")
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Nextcloud Docker - Commandes disponibles:"
|
@echo "Nextcloud Docker - Commandes disponibles:"
|
||||||
@echo " make up - Démarrer les services"
|
@echo ""
|
||||||
@echo " make down - Arrêter les services"
|
@echo "Services:"
|
||||||
@echo " make restart - Redémarrer"
|
@echo " make up - Démarrer tous les services Docker"
|
||||||
@echo " make logs - Voir les logs"
|
@echo " make down - Arrêter et supprimer les containers"
|
||||||
@echo " make ps - Status des containers"
|
@echo " make restart - Redémarrer tous les services"
|
||||||
@echo " make occ - Lancer une commande occ"
|
@echo " make ps - Lister les containers actifs"
|
||||||
@echo " make backup - Backup complet"
|
@echo " make logs - Afficher les logs Nextcloud en temps réel"
|
||||||
@echo " make restore - Restaurer un backup"
|
@echo " make logs-all - Afficher les logs de tous les containers"
|
||||||
@echo " make update - Mettre à jour Nextcloud"
|
@echo ""
|
||||||
@echo " make health - Vérifier la santé du système"
|
@echo "Maintenance:"
|
||||||
|
@echo " make backup - Backup complet (DB + fichiers + config)"
|
||||||
|
@echo " → Active mode maintenance"
|
||||||
|
@echo " → Sauvegarde MariaDB, config, données, apps"
|
||||||
|
@echo " → Désactive mode maintenance"
|
||||||
|
@echo " → Archive dans ./backups/"
|
||||||
|
@echo ""
|
||||||
|
@echo " make update - Mise à jour Nextcloud (avec backup auto)"
|
||||||
|
@echo " → Backup de sécurité automatique"
|
||||||
|
@echo " → Pull nouvelle image Docker"
|
||||||
|
@echo " → Restart avec nouvelle version"
|
||||||
|
@echo " → Upgrade base de données"
|
||||||
|
@echo " → Optimisations post-update"
|
||||||
|
@echo ""
|
||||||
|
@echo " make restore FILE=<backup.tar.gz>"
|
||||||
|
@echo " - Restaurer depuis un backup"
|
||||||
|
@echo " → Arrêt des services"
|
||||||
|
@echo " → Restauration DB + fichiers"
|
||||||
|
@echo " → Redémarrage et réparation"
|
||||||
|
@echo ""
|
||||||
|
@echo " make recover - Récupération après erreur"
|
||||||
|
@echo " → Arrêt/nettoyage des containers"
|
||||||
|
@echo " → Redémarrage propre"
|
||||||
|
@echo " → Désactivation mode maintenance"
|
||||||
|
@echo ""
|
||||||
|
@echo "Monitoring:"
|
||||||
|
@echo " make health - Health check complet du système"
|
||||||
|
@echo " → Docker, containers, Nextcloud, DB, Redis"
|
||||||
|
@echo " → Espace disque, backups, logs"
|
||||||
|
@echo ""
|
||||||
|
@echo "Automatisation:"
|
||||||
|
@echo " make cron-status - Afficher le statut et le planning des backups auto"
|
||||||
|
@echo " make cron-logs - Afficher les logs des tâches cron"
|
||||||
|
@echo ""
|
||||||
|
@echo "Outils:"
|
||||||
|
@echo " make occ <cmd> - Exécuter une commande OCC Nextcloud"
|
||||||
|
@echo " make shell - Ouvrir un shell dans le container Nextcloud"
|
||||||
|
@echo " make db-shell - Ouvrir un shell MySQL/MariaDB"
|
||||||
|
@echo " make redis-shell - Ouvrir un shell Redis"
|
||||||
|
@echo " make permissions - Réparer les permissions des fichiers"
|
||||||
|
@echo " make clean - Nettoyer les logs et fichiers temporaires"
|
||||||
|
|
||||||
up:
|
up:
|
||||||
docker-compose up -d
|
$(DOCKER_COMPOSE) up -d
|
||||||
|
|
||||||
down:
|
down:
|
||||||
docker-compose down
|
$(DOCKER_COMPOSE) down
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
docker-compose restart
|
$(DOCKER_COMPOSE) restart
|
||||||
|
|
||||||
logs:
|
logs:
|
||||||
docker-compose logs -f --tail=100 nextcloud
|
$(DOCKER_COMPOSE) logs -f --tail=100 nextcloud
|
||||||
|
|
||||||
|
logs-all:
|
||||||
|
$(DOCKER_COMPOSE) logs -f --tail=50
|
||||||
|
|
||||||
ps:
|
ps:
|
||||||
docker-compose ps
|
$(DOCKER_COMPOSE) ps
|
||||||
|
|
||||||
|
shell:
|
||||||
|
$(DOCKER_COMPOSE) exec nextcloud /bin/bash
|
||||||
|
|
||||||
|
db-shell:
|
||||||
|
$(DOCKER_COMPOSE) exec db mysql -u"$$MYSQL_USER" -p"$$MYSQL_PASSWORD" "$$MYSQL_DATABASE"
|
||||||
|
|
||||||
|
redis-shell:
|
||||||
|
@if [ -n "$(REDIS_HOST_PASSWORD)" ]; then \
|
||||||
|
$(DOCKER_COMPOSE) exec redis redis-cli -a "$(REDIS_HOST_PASSWORD)"; \
|
||||||
|
else \
|
||||||
|
$(DOCKER_COMPOSE) exec redis redis-cli; \
|
||||||
|
fi
|
||||||
|
|
||||||
occ:
|
occ:
|
||||||
@bash scripts/occ.sh $(filter-out $@,$(MAKECMDGOALS))
|
@bash scripts/occ.sh $(filter-out $@,$(MAKECMDGOALS))
|
||||||
|
|
||||||
backup:
|
backup:
|
||||||
@bash scripts/backup.sh
|
@bash scripts/backup.sh
|
||||||
|
|
||||||
restore:
|
restore:
|
||||||
@bash scripts/restore.sh
|
@if [ -z "$(FILE)" ]; then \
|
||||||
|
echo "❌ Erreur: Spécifiez le fichier de backup avec FILE=<fichier>"; \
|
||||||
|
echo "Exemple: make restore FILE=./backups/nextcloud_backup_20231217_123456.tar.gz"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "Backups disponibles:"; \
|
||||||
|
find ./backups -name "nextcloud_backup_*.tar.gz" -type f -printf '%T+ %p\n' 2>/dev/null | sort -r | head -5; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
@bash scripts/restore.sh "$(FILE)"
|
||||||
|
|
||||||
update:
|
update:
|
||||||
@bash scripts/update.sh
|
@bash scripts/update.sh
|
||||||
|
|
||||||
health:
|
health:
|
||||||
@docker-compose exec nextcloud php occ status
|
@bash scripts/check-health.sh
|
||||||
@docker-compose exec nextcloud php occ config:list system
|
|
||||||
@docker-compose exec db mysql -u$$MYSQL_USER -p$$MYSQL_PASSWORD -e "SELECT 1"
|
recover:
|
||||||
|
@bash scripts/recover.sh
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
@echo "Réparation des permissions..."
|
||||||
|
$(DOCKER_COMPOSE) exec -u root nextcloud chown -R www-data:www-data /var/www/html/data /var/www/html/config /var/www/html/custom_apps
|
||||||
|
@echo "✅ Permissions réparées"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "Nettoyage des logs et fichiers temporaires..."
|
||||||
|
@find ./logs -type f -mtime +30 -delete 2>/dev/null && echo "✅ Logs > 30 jours supprimés" || true
|
||||||
|
@rm -f /tmp/nextcloud_*.lock 2>/dev/null && echo "✅ Fichiers lock supprimés" || true
|
||||||
|
@$(DOCKER_COMPOSE) exec -T nextcloud php occ files:cleanup 2>/dev/null && echo "✅ Fichiers orphelins nettoyés" || true
|
||||||
|
@echo "✅ Nettoyage terminé"
|
||||||
|
|
||||||
|
cron-status:
|
||||||
|
@echo "=== Statut du service de backup automatique ==="
|
||||||
|
@echo ""
|
||||||
|
@echo "Container backup-cron:"
|
||||||
|
@$(DOCKER_COMPOSE) ps backup-cron
|
||||||
|
@echo ""
|
||||||
|
@echo "Planning des tâches:"
|
||||||
|
@$(DOCKER_COMPOSE) exec -T backup-cron cat /etc/crontabs/root 2>/dev/null | grep -v "^#" | grep -v "^$$" || echo "⚠ Container non démarré"
|
||||||
|
@echo ""
|
||||||
|
@echo "Heure du container:"
|
||||||
|
@$(DOCKER_COMPOSE) exec -T backup-cron date 2>/dev/null || echo "⚠ Container non démarré"
|
||||||
|
|
||||||
|
cron-logs:
|
||||||
|
@echo "=== Logs des tâches automatiques ==="
|
||||||
|
@echo ""
|
||||||
|
@echo "Logs de backup (10 dernières lignes):"
|
||||||
|
@tail -n 10 ./logs/cron_backup.log 2>/dev/null || echo "Aucun log de backup"
|
||||||
|
@echo ""
|
||||||
|
@echo "Logs de health check (10 dernières lignes):"
|
||||||
|
@tail -n 10 ./logs/cron_health.log 2>/dev/null || echo "Aucun log de health check"
|
||||||
|
@echo ""
|
||||||
|
@echo "Logs de nettoyage (10 dernières lignes):"
|
||||||
|
@tail -n 10 ./logs/cron_clean.log 2>/dev/null || echo "Aucun log de nettoyage"
|
||||||
|
|
||||||
|
# Catch-all target pour permettre les arguments aux commandes occ et restore
|
||||||
|
%:
|
||||||
|
@:
|
||||||
|
|||||||
660
README.md
660
README.md
@@ -1,113 +1,665 @@
|
|||||||
# Nextcloud Self-Hosted
|
# Nextcloud Docker Deployment
|
||||||
|
|
||||||
Configuration Nextcloud en production pour agence66.fr
|
Déploiement Nextcloud avec Docker Compose comprenant MariaDB 10.11, Redis (cache), service cron intégré et support Traefik pour le reverse proxy.
|
||||||
|
|
||||||
## 🚀 Déploiement initial
|
## Table des matières
|
||||||
|
|
||||||
### 1. Cloner le repo
|
- [Architecture](#architecture)
|
||||||
|
- [Prérequis](#prérequis)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Configuration](#configuration)
|
||||||
|
- [Démarrage](#démarrage)
|
||||||
|
- [Maintenance](#️-maintenance)
|
||||||
|
- [Résolution de problèmes](#-résolution-de-problèmes)
|
||||||
|
- [Monitoring](#-monitoring)
|
||||||
|
- [Sécurité](#-sécurité)
|
||||||
|
|
||||||
\`\`\`bash
|
## Architecture
|
||||||
git clone https://gitea.agence66.fr/vous/nextcloud.git
|
|
||||||
cd nextcloud
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 2. Configuration
|
Le déploiement comprend 5 services:
|
||||||
|
|
||||||
\`\`\`bash
|
- **nextcloud**: Application Nextcloud avec image personnalisée (inclut ffmpeg) - port 127.0.0.1:8888:80
|
||||||
|
- **db**: MariaDB 10.11 avec healthcheck
|
||||||
|
- **redis**: Cache Redis avec politique LRU (512MB max)
|
||||||
|
- **cron**: Tâches planifiées Nextcloud (préviews, nettoyage, etc.)
|
||||||
|
- **backup-cron**: Système de backup automatisé (quotidien)
|
||||||
|
|
||||||
|
**Réseaux**:
|
||||||
|
|
||||||
|
- `nextcloud-net`: Réseau interne pour la communication entre services
|
||||||
|
- `traefik-net`: Réseau externe pour Traefik (reverse proxy)
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
- Docker >= 20.10
|
||||||
|
- Docker Compose >= 2.0
|
||||||
|
- Traefik configuré avec réseau `traefik-net` (pour exposition HTTPS)
|
||||||
|
- Nom de domaine configuré avec certificat SSL
|
||||||
|
- Minimum 2GB RAM recommandé
|
||||||
|
- Minimum 10GB d'espace disque
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. **Cloner le dépôt**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd agence66-nextcloud-docker
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configurer l'environnement**
|
||||||
|
|
||||||
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
nano .env # Éditer avec vos valeurs
|
nano .env
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
Générer des mots de passe sécurisés:
|
3. **Générer des mots de passe sécurisés**
|
||||||
\`\`\`bash
|
|
||||||
openssl rand -base64 32 # Pour chaque secret
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 3. Démarrage
|
```bash
|
||||||
|
# Génération pour chaque secret requis
|
||||||
|
openssl rand -base64 32
|
||||||
|
```
|
||||||
|
|
||||||
\`\`\`bash
|
Variables importantes à configurer dans `.env`:
|
||||||
|
|
||||||
|
- `MYSQL_DATABASE`: Nom de la base de données (défaut: nextcloud)
|
||||||
|
- `MYSQL_USER`: Utilisateur de la base de données
|
||||||
|
- `MYSQL_PASSWORD`: Mot de passe de la base de données
|
||||||
|
- `MYSQL_ROOT_PASSWORD`: Mot de passe root MariaDB
|
||||||
|
- `REDIS_HOST_PASSWORD`: Mot de passe Redis
|
||||||
|
- `NEXTCLOUD_DOMAIN`: Votre nom de domaine
|
||||||
|
- `OVERWRITE_PROTOCOL`: Protocole (http/https)
|
||||||
|
- `OVERWRITE_HOST`: Hôte public (optionnel)
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Variables d'environnement
|
||||||
|
|
||||||
|
Créez votre fichier `.env` basé sur `.env.example`:
|
||||||
|
|
||||||
|
| Variable | Description | Exemple |
|
||||||
|
| ---------------------- | --------------------------- | ------------------- |
|
||||||
|
| `MYSQL_DATABASE` | Nom de la base de données | `nextcloud` |
|
||||||
|
| `MYSQL_USER` | Utilisateur base de données | `nextcloud` |
|
||||||
|
| `MYSQL_PASSWORD` | Mot de passe utilisateur DB | `********` |
|
||||||
|
| `MYSQL_ROOT_PASSWORD` | Mot de passe root MariaDB | `********` |
|
||||||
|
| `REDIS_HOST_PASSWORD` | Mot de passe Redis | `********` |
|
||||||
|
| `NEXTCLOUD_DOMAIN` | Domaine de confiance | `cloud.example.com` |
|
||||||
|
| `OVERWRITE_PROTOCOL` | Protocole (http/https) | `https` |
|
||||||
|
| `OVERWRITE_HOST` | Hôte public | `cloud.example.com` |
|
||||||
|
| `TRUSTED_PROXIES` | Proxies de confiance | `172.18.0.0/16` |
|
||||||
|
| `OVERWRITE_CLI_URL` | URL pour CLI (optionnel) | `https://...` |
|
||||||
|
|
||||||
|
### Volumes
|
||||||
|
|
||||||
|
Les données persistantes sont stockées dans:
|
||||||
|
|
||||||
|
- `./data`: Fichiers Nextcloud et données utilisateurs
|
||||||
|
- `./db`: Base de données MariaDB
|
||||||
|
- `./db-config`: Configuration MariaDB personnalisée
|
||||||
|
|
||||||
|
### Configuration PHP
|
||||||
|
|
||||||
|
Les paramètres PHP sont préconfigurés dans docker-compose.yml:
|
||||||
|
|
||||||
|
| Paramètre | Valeur | Description |
|
||||||
|
| ------------------------- | ------ | ------------------------------- |
|
||||||
|
| `PHP_MEMORY_LIMIT` | 4096M | Mémoire allouée à PHP |
|
||||||
|
| `PHP_UPLOAD_MAX_FILESIZE` | 2G | Taille max d'upload |
|
||||||
|
| `PHP_POST_MAX_SIZE` | 2G | Taille max POST |
|
||||||
|
| `PHP_MAX_EXECUTION_TIME` | 1800s | Timeout d'exécution (30min) |
|
||||||
|
| `PHP_MAX_INPUT_TIME` | 1800s | Timeout lecture données (30min) |
|
||||||
|
| `APACHE_BODY_LIMIT` | 2GB | Limite Apache pour le body |
|
||||||
|
|
||||||
|
Ces valeurs permettent l'upload de fichiers jusqu'à 2GB.
|
||||||
|
|
||||||
|
### Image Docker personnalisée
|
||||||
|
|
||||||
|
Le projet utilise une image Docker personnalisée basée sur `nextcloud:latest` qui inclut **ffmpeg** pour la génération de previews vidéo (.mov, .mp4, etc.).
|
||||||
|
|
||||||
|
**Dockerfile:**
|
||||||
|
```dockerfile
|
||||||
|
FROM nextcloud:latest
|
||||||
|
|
||||||
|
# Installer ffmpeg pour les previews vidéo
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ffmpeg \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
```
|
||||||
|
|
||||||
|
**Builder l'image:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Builder l'image custom
|
||||||
|
docker compose build nextcloud
|
||||||
|
|
||||||
|
# Ou forcer le rebuild
|
||||||
|
docker compose build --no-cache nextcloud
|
||||||
|
```
|
||||||
|
|
||||||
|
**Vérifier ffmpeg:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose exec nextcloud ffmpeg -version
|
||||||
|
```
|
||||||
|
|
||||||
|
**Activer les previews vidéo:**
|
||||||
|
|
||||||
|
Après le premier démarrage, activez les providers de preview pour les vidéos:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose exec -u www-data nextcloud php occ config:system:set enabledPreviewProviders 0 --value="OC\\Preview\\Movie"
|
||||||
|
docker compose exec -u www-data nextcloud php occ config:system:set enabledPreviewProviders 1 --value="OC\\Preview\\PNG"
|
||||||
|
docker compose exec -u www-data nextcloud php occ config:system:set enabledPreviewProviders 2 --value="OC\\Preview\\JPEG"
|
||||||
|
docker compose exec -u www-data nextcloud php occ config:system:set enabledPreviewProviders 3 --value="OC\\Preview\\GIF"
|
||||||
|
docker compose exec -u www-data nextcloud php occ config:system:set enabledPreviewProviders 4 --value="OC\\Preview\\BMP"
|
||||||
|
|
||||||
|
# Générer les previews pour un utilisateur
|
||||||
|
docker compose exec -u www-data nextcloud php occ preview:generate-all nom_utilisateur
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** L'image est buildée localement et taguée `nextcloud-custom:latest`. Lors des mises à jour Nextcloud, pensez à rebuild l'image.
|
||||||
|
|
||||||
|
# Server Transport Traefik
|
||||||
|
|
||||||
|
Ajouter à traefik.yml :
|
||||||
|
```yml
|
||||||
|
serversTransport:
|
||||||
|
nextcloud-transport:
|
||||||
|
forwardingTimeouts:
|
||||||
|
dialTimeout: 30s
|
||||||
|
responseHeaderTimeout: 0s
|
||||||
|
idleConnTimeout: 3600s
|
||||||
|
```
|
||||||
|
OU au docker-compose.yml
|
||||||
|
```yml
|
||||||
|
command:
|
||||||
|
- "--serverstransport.forwardingtimeouts.dialtimeout=30s"
|
||||||
|
- "--serverstransport.forwardingtimeouts.responseheadertimeout=0"
|
||||||
|
- "--serverstransport.forwardingtimeouts.idleconntimeout=3600s"
|
||||||
|
```
|
||||||
|
### Configuration Apache pour Traefik
|
||||||
|
|
||||||
|
Le fichier `apache/nextcloud.conf` configure Apache pour fonctionner correctement derrière le reverse proxy Traefik.
|
||||||
|
|
||||||
|
**Configuration incluse:**
|
||||||
|
|
||||||
|
- **RemoteIP**: Récupération de l'IP réelle du client (pas celle de Traefik)
|
||||||
|
- **X-Forwarded-Proto**: Détection automatique HTTPS depuis Traefik
|
||||||
|
- **Headers de sécurité**: X-Frame-Options, X-Content-Type-Options, etc.
|
||||||
|
- **WebDAV désactivé**: Évite les conflits (Nextcloud gère son propre WebDAV)
|
||||||
|
|
||||||
|
**Activation des modules Apache:**
|
||||||
|
|
||||||
|
Lors du premier déploiement, activez les modules nécessaires:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Activer tous les modules en une commande
|
||||||
|
docker compose exec nextcloud bash -c "a2enmod headers rewrite dir mime remoteip env && apache2ctl graceful"
|
||||||
|
|
||||||
|
# Redémarrer Nextcloud pour appliquer les changements
|
||||||
|
docker compose restart nextcloud
|
||||||
|
```
|
||||||
|
|
||||||
|
**Modules activés:**
|
||||||
|
|
||||||
|
| Module | Utilité |
|
||||||
|
| ---------- | ---------------------------------------------------- |
|
||||||
|
| `headers` | Gestion des headers HTTP (sécurité) |
|
||||||
|
| `rewrite` | URL rewriting (requis pour .htaccess) |
|
||||||
|
| `dir` | DirectoryIndex (index.php, etc.) |
|
||||||
|
| `mime` | Types MIME (CSS, JS, etc.) |
|
||||||
|
| `remoteip` | Récupération IP client via X-Forwarded-For |
|
||||||
|
| `env` | Variables d'environnement (détection HTTPS) |
|
||||||
|
|
||||||
|
**Note**: Les modules `headers`, `rewrite`, `dir`, et `mime` sont normalement activés par défaut dans l'image `nextcloud:latest`. Seuls `remoteip` et `env` doivent être activés manuellement.
|
||||||
|
|
||||||
|
**Vérification:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier qu'Apache utilise bien la configuration
|
||||||
|
docker compose exec nextcloud apache2ctl -M | grep -E "(headers|rewrite|remoteip|env)"
|
||||||
|
|
||||||
|
# Vérifier les logs avec IP réelle
|
||||||
|
docker compose logs nextcloud --tail=20
|
||||||
|
```
|
||||||
|
|
||||||
|
## Démarrage
|
||||||
|
|
||||||
|
### Première installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Builder l'image personnalisée (inclut ffmpeg)
|
||||||
|
docker compose build nextcloud
|
||||||
|
|
||||||
|
# Démarrer tous les services
|
||||||
make up
|
make up
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### 4. Configuration initiale
|
# Vérifier que tous les containers sont actifs
|
||||||
|
make ps
|
||||||
|
|
||||||
Accéder à https://cloud.agence66.fr et créer le compte admin.
|
# Vérifier l'état de Nextcloud
|
||||||
|
make health
|
||||||
|
```
|
||||||
|
|
||||||
Ensuite, optimiser:
|
**Accès à l'instance**:
|
||||||
\`\`\`bash
|
|
||||||
make occ config:system:set memcache.local --value='\\OC\\Memcache\\APCu'
|
- **Via Traefik** (production): `https://votre-domaine.com` (recommandé)
|
||||||
make occ config:system:set memcache.locking --value='\\OC\\Memcache\\Redis'
|
- **Accès direct** (développement): `http://localhost:8888`
|
||||||
make occ config:system:set default_phone_region --value='FR'
|
|
||||||
\`\`\`
|
**Note**: En production, Traefik doit être configuré pour exposer Nextcloud via HTTPS. Le port 8888 n'écoute que sur 127.0.0.1 pour des raisons de sécurité.
|
||||||
|
|
||||||
|
### Arrêter les services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make down
|
||||||
|
```
|
||||||
|
|
||||||
|
### Redémarrer les services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make restart
|
||||||
|
```
|
||||||
|
|
||||||
## 🛠️ Maintenance
|
## 🛠️ Maintenance
|
||||||
|
|
||||||
### Backup quotidien
|
### Backup pré-mise à jour
|
||||||
|
|
||||||
\`\`\`bash
|
Créer une sauvegarde de sécurité avant une mise à jour:
|
||||||
|
|
||||||
|
```bash
|
||||||
make backup
|
make backup
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
Configurer un cron sur le serveur:
|
**Actions effectuées par le script:**
|
||||||
\`\`\`bash
|
|
||||||
0 3 \* \* \* cd /path/to/nextcloud && make backup
|
1. ⏸️ Active le mode maintenance Nextcloud
|
||||||
\`\`\`
|
2. 💾 Sauvegarde la base de données MariaDB (mysqldump avec transactions)
|
||||||
|
3. ⚙️ Sauvegarde la configuration (`/var/www/html/config`)
|
||||||
|
4. 📁 Sauvegarde les données utilisateurs (avec exclusions: previews, cache, thumbnails)
|
||||||
|
5. 📦 Sauvegarde les apps personnalisées (`custom_apps`)
|
||||||
|
6. ▶️ Désactive le mode maintenance
|
||||||
|
7. 🗜️ Compresse le tout en `.tar.gz` dans `./backups/`
|
||||||
|
8. 🧹 Nettoie les backups de plus de 7 jours
|
||||||
|
|
||||||
|
**Sécurité:**
|
||||||
|
- Tous les tar s'exécutent dans le container en tant que `www-data`
|
||||||
|
- Mots de passe sécurisés via `MYSQL_PWD` (pas visible dans `ps`)
|
||||||
|
- Cleanup automatique en cas d'erreur avec trap handler
|
||||||
|
|
||||||
|
**Note**: Un service cron intégré est déjà configuré dans docker-compose.yml pour les tâches planifiées Nextcloud (préviews, nettoyage, etc.)
|
||||||
|
|
||||||
|
### Restauration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lister les backups disponibles
|
||||||
|
ls -lh backups/
|
||||||
|
|
||||||
|
# Restaurer depuis une sauvegarde
|
||||||
|
make restore backups/nextcloud_backup_YYYYMMDD_HHMMSS.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
**Actions effectuées par le script:**
|
||||||
|
|
||||||
|
1. ⚠️ Demande confirmation (opération destructive!)
|
||||||
|
2. 📂 Extrait l'archive dans un répertoire temporaire
|
||||||
|
3. ✅ Valide le contenu de l'archive (type MIME, fichiers requis)
|
||||||
|
4. ⏹️ Arrête tous les services Docker
|
||||||
|
5. 💾 Restaure la base de données MariaDB
|
||||||
|
- Démarre uniquement le container DB
|
||||||
|
- Attend que MariaDB soit prêt (health check)
|
||||||
|
- Importe le dump SQL
|
||||||
|
6. ▶️ Démarre tous les services
|
||||||
|
7. 📁 Restaure les fichiers (config, données, apps) via le container
|
||||||
|
8. 🔧 Exécute `maintenance:repair` pour corriger les éventuels problèmes
|
||||||
|
9. ▶️ Désactive le mode maintenance
|
||||||
|
10. 🔍 Scanne tous les fichiers avec `files:scan --all`
|
||||||
|
11. 🧹 Nettoie le répertoire temporaire
|
||||||
|
|
||||||
|
**Sécurité:**
|
||||||
|
- Validation du chemin (protection path traversal)
|
||||||
|
- Vérification du type de fichier (gzip)
|
||||||
|
- Restauration via container en tant que `www-data`
|
||||||
|
- Cleanup garanti avec trap handler
|
||||||
|
|
||||||
### Mise à jour
|
### Mise à jour
|
||||||
|
|
||||||
\`\`\`bash
|
Mettre à jour Nextcloud vers la dernière version:
|
||||||
|
|
||||||
|
```bash
|
||||||
make update
|
make update
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
|
**Le script effectue automatiquement un backup avant la mise à jour!**
|
||||||
|
|
||||||
|
**Actions effectuées par le script:**
|
||||||
|
|
||||||
|
1. 💾 **Backup automatique de sécurité**
|
||||||
|
- Exécute `scripts/backup.sh` complet
|
||||||
|
- Archive créée dans `./backups/`
|
||||||
|
2. 🔨 Rebuild l'image personnalisée avec la nouvelle version Nextcloud
|
||||||
|
3. ⏸️ Active le mode maintenance
|
||||||
|
4. 🔄 Redémarre les containers avec `--force-recreate`
|
||||||
|
5. ⏳ Attend que Nextcloud soit prêt (health check jusqu'à 60s)
|
||||||
|
6. ▶️ Désactive temporairement le mode maintenance
|
||||||
|
7. ⬆️ Exécute `occ upgrade` (migrations base de données)
|
||||||
|
8. 🔍 Scanne tous les fichiers (`files:scan --all`)
|
||||||
|
9. 📊 Ajoute les indices manquants (`db:add-missing-indices`)
|
||||||
|
10. 🔧 Convertit les colonnes en bigint (`db:convert-filecache-bigint`)
|
||||||
|
11. ▶️ Désactive le mode maintenance
|
||||||
|
12. ✅ Affiche le statut final
|
||||||
|
|
||||||
|
**Vérification post-update:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier la version et l'état
|
||||||
|
make occ status
|
||||||
|
|
||||||
|
# Vérifier la santé globale
|
||||||
|
make health
|
||||||
|
```
|
||||||
|
|
||||||
|
**En cas de problème:**
|
||||||
|
|
||||||
|
Si la mise à jour échoue, restaurez le backup automatique créé à l'étape 1:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lister les backups (le plus récent est celui de l'update)
|
||||||
|
ls -lht backups/ | head
|
||||||
|
|
||||||
|
# Restaurer
|
||||||
|
make restore backups/nextcloud_backup_YYYYMMDD_HHMMSS.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
**Sécurité:**
|
||||||
|
- Backup automatique avant toute modification
|
||||||
|
- Trap handler pour cleanup en cas d'erreur
|
||||||
|
- Mode maintenance automatiquement désactivé même en cas d'échec
|
||||||
|
- Instructions de rollback affichées en cas d'erreur
|
||||||
|
|
||||||
### Commandes OCC
|
### Commandes OCC
|
||||||
|
|
||||||
\`\`\`bash
|
OCC (occ = ownCloud Console) est l'interface en ligne de commande de Nextcloud:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier le status de l'instance
|
||||||
make occ status
|
make occ status
|
||||||
|
|
||||||
|
# Lister les utilisateurs
|
||||||
make occ user:list
|
make occ user:list
|
||||||
|
|
||||||
|
# Scanner tous les fichiers
|
||||||
make occ files:scan --all
|
make occ files:scan --all
|
||||||
|
|
||||||
|
# Lister les applications installées
|
||||||
make occ app:list
|
make occ app:list
|
||||||
\`\`\`
|
|
||||||
|
# Activer/désactiver le mode maintenance
|
||||||
|
make occ maintenance:mode --on
|
||||||
|
make occ maintenance:mode --off
|
||||||
|
```
|
||||||
|
|
||||||
## 🔧 Résolution de problèmes
|
## 🔧 Résolution de problèmes
|
||||||
|
|
||||||
### Erreur 423 WebDAV Locked
|
### Erreur 423 WebDAV Locked
|
||||||
|
|
||||||
\`\`\`bash
|
Si vous rencontrez des erreurs de fichiers verrouillés:
|
||||||
|
|
||||||
|
```bash
|
||||||
make occ files:cleanup
|
make occ files:cleanup
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
### Performance lente
|
### Performance lente
|
||||||
|
|
||||||
\`\`\`bash
|
Optimisations recommandées:
|
||||||
|
|
||||||
# Vérifier les indices
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ajouter les indices manquants en base de données
|
||||||
make occ db:add-missing-indices
|
make occ db:add-missing-indices
|
||||||
|
|
||||||
# Nettoyer les fichiers supprimés
|
# Convertir les colonnes en big int si nécessaire
|
||||||
|
make occ db:convert-filecache-bigint
|
||||||
|
|
||||||
|
# Nettoyer les fichiers supprimés
|
||||||
make occ files:cleanup
|
make occ files:cleanup
|
||||||
|
|
||||||
# Optimiser les previews
|
# Optimiser la génération des previews
|
||||||
|
|
||||||
make occ config:app:set previewgenerator squareSizes --value="256 512"
|
make occ config:app:set previewgenerator squareSizes --value="256 512"
|
||||||
make occ config:app:set previewgenerator widthSizes --value="256 512 1024"
|
make occ config:app:set previewgenerator widthSizes --value="256 512 1024"
|
||||||
make occ config:app:set previewgenerator heightSizes --value="256 512 1024"
|
make occ config:app:set previewgenerator heightSizes --value="256 512 1024"
|
||||||
\`\`\`
|
|
||||||
|
# Générer les previews
|
||||||
|
make occ preview:generate-all
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problèmes de permissions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Réparer les permissions des fichiers
|
||||||
|
docker compose exec -u www-data nextcloud chown -R www-data:www-data /var/www/html/data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Espace disque insuffisant
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Nettoyer les anciennes versions de fichiers
|
||||||
|
make occ versions:cleanup
|
||||||
|
|
||||||
|
# Nettoyer la corbeille
|
||||||
|
make occ trashbin:cleanup --all-users
|
||||||
|
|
||||||
|
# Vérifier l'utilisation de l'espace
|
||||||
|
du -sh ./data # Données Nextcloud
|
||||||
|
du -sh ./db # Base de données MariaDB
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mode débogage
|
||||||
|
|
||||||
|
⚠️ **IMPORTANT**: Le mode débogage ne doit **JAMAIS** être activé en production!
|
||||||
|
|
||||||
|
**Vérifier l'état du mode débogage:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make occ config:system:get debug
|
||||||
|
```
|
||||||
|
|
||||||
|
**Désactiver le mode débogage (PRODUCTION):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via OCC (recommandé)
|
||||||
|
make occ config:system:set debug --value=false --type=boolean
|
||||||
|
|
||||||
|
# OU éditer manuellement config.php
|
||||||
|
docker-compose exec nextcloud nano /var/www/html/config/config.php
|
||||||
|
# Chercher 'debug' => true, et changer en false ou supprimer la ligne
|
||||||
|
```
|
||||||
|
|
||||||
|
**Activer temporairement pour diagnostiquer un problème (DÉVELOPPEMENT UNIQUEMENT):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Activer
|
||||||
|
make occ config:system:set debug --value=true --type=boolean
|
||||||
|
|
||||||
|
# IMPORTANT: Désactiver immédiatement après le diagnostic!
|
||||||
|
make occ config:system:set debug --value=false --type=boolean
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pourquoi c'est dangereux en production:**
|
||||||
|
|
||||||
|
- 🚨 **Sécurité**: Expose des informations sensibles (chemins, configuration, requêtes SQL)
|
||||||
|
- 🐌 **Performance**: Génère énormément de logs et ralentit l'application
|
||||||
|
- 💾 **Espace disque**: Remplit rapidement le disque avec des logs détaillés
|
||||||
|
- 📊 **Conformité**: Peut logger des données personnelles (RGPD)
|
||||||
|
|
||||||
|
### Messages de debug dans la console navigateur
|
||||||
|
|
||||||
|
Si vous voyez des messages `[DEBUG]` dans la console JavaScript du navigateur (F12), même avec `debug => false`:
|
||||||
|
|
||||||
|
**1. Vider tous les caches:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Cache Nextcloud
|
||||||
|
make occ maintenance:repair --include-expensive
|
||||||
|
|
||||||
|
# Cache Redis
|
||||||
|
docker compose exec redis redis-cli -a VOTRE_PASSWORD_REDIS FLUSHALL
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Vérifier le niveau de log:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Niveau recommandé pour production: 2 (Warning)
|
||||||
|
make occ config:system:set loglevel --value=2 --type=integer
|
||||||
|
```
|
||||||
|
|
||||||
|
**Niveaux de log disponibles:**
|
||||||
|
- 0 = Debug (tous les messages)
|
||||||
|
- 1 = Info
|
||||||
|
- 2 = Warning (recommandé production)
|
||||||
|
- 3 = Error
|
||||||
|
- 4 = Fatal
|
||||||
|
|
||||||
|
**3. Hard refresh dans le navigateur:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Firefox/Chrome: Ctrl + Shift + R
|
||||||
|
# Ou vider le cache du navigateur pour le domaine Nextcloud
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. Redémarrer les services:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose restart nextcloud redis
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problèmes de synchronisation client
|
||||||
|
|
||||||
|
Si le client de synchronisation Nextcloud affiche "error transfering, server replied not found":
|
||||||
|
|
||||||
|
**1. Scanner les fichiers pour mettre à jour l'index:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Scanner tous les fichiers d'un utilisateur
|
||||||
|
make occ files:scan nom_utilisateur
|
||||||
|
|
||||||
|
# Scanner uniquement un dossier spécifique
|
||||||
|
make occ files:scan --path="/nom_utilisateur/files/Dossier"
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Nettoyer les verrous de fichiers:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make occ files:cleanup
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Vérifier les logs pour identifier le fichier problématique:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Logs en temps réel
|
||||||
|
docker compose logs -f nextcloud --tail=50
|
||||||
|
|
||||||
|
# Rechercher les erreurs 404
|
||||||
|
docker compose logs nextcloud | grep "404"
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. En dernier recours, réinitialiser la synchronisation:**
|
||||||
|
- Dans le client Nextcloud: supprimer le compte et le re-configurer
|
||||||
|
- Cela forcera une synchronisation complète
|
||||||
|
|
||||||
## 📊 Monitoring
|
## 📊 Monitoring
|
||||||
|
|
||||||
\`\`\`bash
|
### Vérifications de santé
|
||||||
|
|
||||||
# Status
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status général
|
||||||
make health
|
make health
|
||||||
|
|
||||||
# Logs en temps réel
|
# Vérifier les containers actifs
|
||||||
|
make ps
|
||||||
|
|
||||||
|
# Voir les logs en temps réel
|
||||||
make logs
|
make logs
|
||||||
|
|
||||||
# Containers actifs
|
# Logs d'un service spécifique
|
||||||
|
docker compose logs -f nextcloud
|
||||||
|
docker compose logs -f db
|
||||||
|
docker compose logs -f redis
|
||||||
|
```
|
||||||
|
|
||||||
make ps
|
### Métriques de performance
|
||||||
\`\`\`
|
|
||||||
|
```bash
|
||||||
|
# Statistiques système
|
||||||
|
make occ status
|
||||||
|
|
||||||
|
# Informations sur la base de données MariaDB
|
||||||
|
docker compose exec db mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.TABLES WHERE table_schema = 'nextcloud';"
|
||||||
|
|
||||||
|
# Utilisation Redis
|
||||||
|
docker compose exec redis redis-cli -a ${REDIS_HOST_PASSWORD} INFO stats
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔒 Sécurité
|
||||||
|
|
||||||
|
### Bonnes pratiques
|
||||||
|
|
||||||
|
1. **Mots de passe forts**: Utilisez `openssl rand -base64 32` pour tous les secrets
|
||||||
|
2. **HTTPS obligatoire**: Configurez SSL/TLS avec Let's Encrypt ou certificats valides
|
||||||
|
3. **Mises à jour régulières**: Exécutez `make backup` puis `make update` mensuellement
|
||||||
|
4. **Sauvegardes**: Utilisez `make backup` avant toute mise à jour (backup serveur quotidien géré au niveau système)
|
||||||
|
5. **Monitoring**: Vérifiez les logs régulièrement pour détecter les activités suspectes
|
||||||
|
6. **Mode débogage désactivé**: Vérifiez avec `make occ config:system:get debug` (doit être `false` ou absent)
|
||||||
|
|
||||||
|
### Sécuriser l'accès
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Activer l'authentification à deux facteurs
|
||||||
|
make occ app:enable twofactor_totp
|
||||||
|
|
||||||
|
# Forcer HTTPS
|
||||||
|
make occ config:system:set overwriteprotocol --value="https"
|
||||||
|
|
||||||
|
# Limiter les tentatives de connexion
|
||||||
|
make occ app:enable bruteforcesettings
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commandes Make disponibles
|
||||||
|
|
||||||
|
| Commande | Description |
|
||||||
|
| -------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||||
|
| `make up` | Démarrer tous les services Docker (nextcloud, db, redis, cron) |
|
||||||
|
| `make down` | Arrêter et supprimer tous les containers |
|
||||||
|
| `make restart` | Redémarrer tous les services |
|
||||||
|
| `make ps` | Lister les containers actifs avec leur état |
|
||||||
|
| `make logs` | Afficher les logs Nextcloud en temps réel (tail -100) |
|
||||||
|
| `make health` | Vérifier l'état: statut Nextcloud + config système + connexion MariaDB |
|
||||||
|
| `make backup` | Backup complet: DB + config + données + apps (avec mode maintenance) |
|
||||||
|
| `make restore <file>` | Restaurer depuis un backup (destructif - demande confirmation) |
|
||||||
|
| `make update` | Mise à jour complète: backup auto + pull + upgrade + optimisations |
|
||||||
|
| `make occ <commande>` | Exécuter une commande OCC Nextcloud (ex: `make occ user:list`) |
|
||||||
|
|
||||||
|
**Exemples d'utilisation:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup et update
|
||||||
|
make backup
|
||||||
|
make update
|
||||||
|
|
||||||
|
# Restaurer un backup spécifique
|
||||||
|
make restore backups/nextcloud_backup_20251215_112450.tar.gz
|
||||||
|
|
||||||
|
# Commandes OCC
|
||||||
|
make occ status
|
||||||
|
make occ user:list
|
||||||
|
make occ files:scan --all
|
||||||
|
```
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
Pour toute question ou problème:
|
||||||
|
|
||||||
|
1. Consultez la [documentation officielle Nextcloud](https://docs.nextcloud.com/)
|
||||||
|
2. Vérifiez les logs: `make logs`
|
||||||
|
3. Consultez les issues du projet
|
||||||
|
|||||||
227
SECURITY.md
Normal file
227
SECURITY.md
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
# Sécurité et Best Practices
|
||||||
|
|
||||||
|
Ce document décrit les mesures de sécurité et les best practices implémentées dans ce projet Nextcloud.
|
||||||
|
|
||||||
|
## ✅ Corrections de Sécurité Appliquées
|
||||||
|
|
||||||
|
### 🔒 Gestion des Secrets
|
||||||
|
|
||||||
|
#### Fichier .env
|
||||||
|
- ✅ `.env` ajouté au `.gitignore` pour éviter de commiter les secrets
|
||||||
|
- ✅ `.env.example` créé avec des instructions claires
|
||||||
|
- ✅ Instructions pour générer des mots de passe forts (min 32 caractères)
|
||||||
|
- ⚠️ **IMPORTANT**: Changez tous les mots de passe par défaut avec:
|
||||||
|
```bash
|
||||||
|
openssl rand -base64 32
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Gestion des Mots de Passe
|
||||||
|
- ✅ `MYSQL_PWD` utilisé pour éviter l'exposition des mots de passe dans les commandes
|
||||||
|
- ✅ Pas de mots de passe en clair dans les logs
|
||||||
|
- ✅ Variables d'environnement chargées de manière sécurisée avec `set -a`
|
||||||
|
|
||||||
|
### 🛡️ Protection des Scripts
|
||||||
|
|
||||||
|
#### Validation des Entrées
|
||||||
|
- ✅ **backup.sh**: Variables requises validées avec `${VAR:?message}`
|
||||||
|
- ✅ **restore.sh**: Protection contre path traversal améliorée
|
||||||
|
- ✅ **restore.sh**: Validation du type de fichier (gzip)
|
||||||
|
- ✅ **restore.sh**: Utilisation de `realpath` pour résoudre les chemins
|
||||||
|
|
||||||
|
#### Sécurité des Opérations
|
||||||
|
- ✅ `set -euo pipefail` dans tous les scripts
|
||||||
|
- ✅ Protection `${VAR:?}` pour éviter les suppressions accidentelles
|
||||||
|
- ✅ Système de lock pour empêcher les backups simultanés
|
||||||
|
- ✅ Fonctions de cleanup avec `trap` pour gérer les erreurs
|
||||||
|
|
||||||
|
### 📊 Logging et Audit
|
||||||
|
|
||||||
|
#### Traçabilité
|
||||||
|
- ✅ Logs centralisés dans `./logs/` avec timestamps
|
||||||
|
- ✅ Fonction `log()` standardisée dans tous les scripts
|
||||||
|
- ✅ Tous les scripts créent des logs horodatés
|
||||||
|
- ✅ Codes de sortie et erreurs loggés
|
||||||
|
|
||||||
|
#### Monitoring
|
||||||
|
- ✅ Script `check-health.sh` pour vérifier l'état du système
|
||||||
|
- ✅ Vérification de l'espace disque avant backup
|
||||||
|
- ✅ Vérification de l'âge des backups
|
||||||
|
|
||||||
|
### 🔐 Intégrité des Données
|
||||||
|
|
||||||
|
#### Checksums
|
||||||
|
- ✅ Génération automatique de checksums SHA256 pour les backups
|
||||||
|
- ✅ Vérification des checksums avant restauration
|
||||||
|
- ✅ Détection de fichiers corrompus
|
||||||
|
|
||||||
|
#### Backups de Sécurité
|
||||||
|
- ✅ Backup automatique de la DB avant restauration
|
||||||
|
- ✅ Backup du `docker-compose.yml` avant mise à jour
|
||||||
|
- ✅ Option de créer un backup avant restauration
|
||||||
|
|
||||||
|
### 🚀 Docker Compose
|
||||||
|
|
||||||
|
#### Compatibilité
|
||||||
|
- ✅ Support de Docker Compose v2 (`docker compose`)
|
||||||
|
- ✅ Fallback vers Docker Compose v1 (`docker-compose`)
|
||||||
|
- ✅ Détection automatique de la version disponible
|
||||||
|
|
||||||
|
## 📋 Checklist de Sécurité
|
||||||
|
|
||||||
|
### Configuration Initiale
|
||||||
|
|
||||||
|
- [ ] Copier `.env.example` vers `.env`
|
||||||
|
- [ ] Générer des mots de passe forts avec `openssl rand -base64 32`
|
||||||
|
- [ ] Modifier tous les mots de passe dans `.env`:
|
||||||
|
- `MYSQL_ROOT_PASSWORD`
|
||||||
|
- `MYSQL_PASSWORD`
|
||||||
|
- `REDIS_HOST_PASSWORD`
|
||||||
|
- [ ] Vérifier que `.env` n'est PAS dans git: `git status`
|
||||||
|
- [ ] Configurer les paramètres de production (domaine, SSL, etc.)
|
||||||
|
|
||||||
|
### Maintenance Régulière
|
||||||
|
|
||||||
|
- [ ] Exécuter `make check-health` régulièrement
|
||||||
|
- [ ] Vérifier les logs dans `./logs/`
|
||||||
|
- [ ] S'assurer que les backups sont créés (< 24h)
|
||||||
|
- [ ] Vérifier l'espace disque disponible
|
||||||
|
- [ ] Tester les restaurations périodiquement
|
||||||
|
|
||||||
|
### Avant une Mise en Production
|
||||||
|
|
||||||
|
- [ ] Tous les mots de passe sont forts et uniques
|
||||||
|
- [ ] SSL/TLS configuré (via Traefik ou autre)
|
||||||
|
- [ ] Domaine configuré dans `TRUSTED_DOMAINS`
|
||||||
|
- [ ] Backups automatiques configurés (cron)
|
||||||
|
- [ ] Logs configurés et monitorés
|
||||||
|
- [ ] Health checks configurés
|
||||||
|
|
||||||
|
## 🔧 Scripts et Outils
|
||||||
|
|
||||||
|
### Scripts de Maintenance
|
||||||
|
|
||||||
|
| Script | Description | Sécurité |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| `backup.sh` | Backup complet | Lock, checksum, vérif espace disque |
|
||||||
|
| `restore.sh` | Restauration | Vérif checksum, backup sécurité DB |
|
||||||
|
| `update.sh` | Mise à jour | Backup auto, rollback docker-compose |
|
||||||
|
| `recover.sh` | Récupération d'erreur | Logs, suggestions dynamiques |
|
||||||
|
| `occ.sh` | Wrapper OCC | Support Docker Compose v2 |
|
||||||
|
| `check-health.sh` | Health check complet | Vérifications système complètes |
|
||||||
|
|
||||||
|
### Commandes Make
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make backup # Créer un backup complet
|
||||||
|
make restore <file> # Restaurer un backup
|
||||||
|
make update # Mettre à jour Nextcloud
|
||||||
|
make check-health # Vérifier l'état du système
|
||||||
|
make recover # Récupérer après une erreur
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚨 Gestion des Incidents
|
||||||
|
|
||||||
|
### En cas d'erreur
|
||||||
|
|
||||||
|
1. **Consulter les logs**:
|
||||||
|
```bash
|
||||||
|
ls -lth ./logs/
|
||||||
|
tail -f ./logs/backup_*.log
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Vérifier l'état du système**:
|
||||||
|
```bash
|
||||||
|
make check-health
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Tenter une récupération**:
|
||||||
|
```bash
|
||||||
|
make recover
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Si nécessaire, restaurer un backup**:
|
||||||
|
```bash
|
||||||
|
make restore backups/nextcloud_backup_YYYYMMDD_HHMMSS.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
### Récupération après Compromission
|
||||||
|
|
||||||
|
Si vous soupçonnez une compromission:
|
||||||
|
|
||||||
|
1. **Arrêter les services immédiatement**:
|
||||||
|
```bash
|
||||||
|
make down
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Analyser les logs**:
|
||||||
|
```bash
|
||||||
|
docker-compose logs > incident_logs.txt
|
||||||
|
cat ./logs/*.log > app_logs.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Restaurer depuis un backup propre**:
|
||||||
|
```bash
|
||||||
|
make restore <backup_avant_incident>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Changer TOUS les mots de passe**
|
||||||
|
5. **Vérifier les utilisateurs et permissions**
|
||||||
|
6. **Mettre à jour vers la dernière version**
|
||||||
|
|
||||||
|
## 📚 Références
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
||||||
|
- [Docker Security Best Practices](https://docs.docker.com/engine/security/)
|
||||||
|
- [Nextcloud Security Hardening](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html)
|
||||||
|
|
||||||
|
### Commandes Utiles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Générer un mot de passe fort
|
||||||
|
openssl rand -base64 32
|
||||||
|
|
||||||
|
# Vérifier les permissions
|
||||||
|
ls -la .env
|
||||||
|
# Devrait être: -rw------- (600)
|
||||||
|
|
||||||
|
# Vérifier qu'aucun secret n'est dans git
|
||||||
|
git grep -i password
|
||||||
|
git grep -i secret
|
||||||
|
|
||||||
|
# Audit de sécurité basique
|
||||||
|
make check-health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Notes de Version
|
||||||
|
|
||||||
|
### Version actuelle
|
||||||
|
|
||||||
|
**Améliorations de sécurité**:
|
||||||
|
- ✅ Protection des secrets (.env hors git)
|
||||||
|
- ✅ Validation des entrées utilisateur
|
||||||
|
- ✅ Checksums pour intégrité des backups
|
||||||
|
- ✅ Logging complet pour audit
|
||||||
|
- ✅ Protection contre path traversal
|
||||||
|
- ✅ Vérifications d'espace disque
|
||||||
|
- ✅ Backups de sécurité automatiques
|
||||||
|
- ✅ Support Docker Compose v2
|
||||||
|
|
||||||
|
**Bugs corrigés**:
|
||||||
|
- ✅ Incohérence BACKUP_RETENTION_DAYS
|
||||||
|
- ✅ Protection find -delete dangereuse
|
||||||
|
- ✅ Path traversal incomplet
|
||||||
|
- ✅ Pas de vérification checksums
|
||||||
|
- ✅ Pas de backup avant restore
|
||||||
|
|
||||||
|
**Fonctionnalités ajoutées**:
|
||||||
|
- ✅ Script de health check complet
|
||||||
|
- ✅ Système de lock pour backups
|
||||||
|
- ✅ Génération automatique de checksums
|
||||||
|
- ✅ Logs centralisés avec timestamps
|
||||||
|
- ✅ Backup dynamique suggéré dans recover
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Date de dernière mise à jour**: 2025-12-17
|
||||||
16
apache/mpm_prefork.conf
Normal file
16
apache/mpm_prefork.conf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# prefork MPM
|
||||||
|
# StartServers: number of server processes to start
|
||||||
|
# MinSpareServers: minimum number of server processes which are kept spare
|
||||||
|
# MaxSpareServers: maximum number of server processes which are kept spare
|
||||||
|
# ServerLimit: maximum value for MaxRequestWorkers (must be set before MaxRequestWorkers)
|
||||||
|
# MaxRequestWorkers: maximum number of server processes allowed to start
|
||||||
|
# MaxConnectionsPerChild: maximum number of requests a server process serves
|
||||||
|
|
||||||
|
<IfModule mpm_prefork_module>
|
||||||
|
ServerLimit 400
|
||||||
|
StartServers 10
|
||||||
|
MinSpareServers 10
|
||||||
|
MaxSpareServers 20
|
||||||
|
MaxRequestWorkers 400
|
||||||
|
MaxConnectionsPerChild 1000
|
||||||
|
</IfModule>
|
||||||
48
apache/nextcloud.conf
Normal file
48
apache/nextcloud.conf
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Configuration pour reverse proxy Traefik
|
||||||
|
# Récupération de l'IP réelle du client via X-Forwarded-For
|
||||||
|
ServerName cloud.agence66.fr
|
||||||
|
|
||||||
|
# Autoriser les caractères spéciaux encodés dans les noms de fichiers
|
||||||
|
AllowEncodedSlashes NoDecode
|
||||||
|
|
||||||
|
RemoteIPHeader X-Forwarded-For
|
||||||
|
RemoteIPTrustedProxy 172.16.0.0/12
|
||||||
|
RemoteIPTrustedProxy 10.0.0.0/8
|
||||||
|
RemoteIPTrustedProxy 192.168.0.0/16
|
||||||
|
|
||||||
|
# Activer la confiance des en-têtes X-Forwarded-Proto
|
||||||
|
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
|
||||||
|
|
||||||
|
# Timeouts pour gros fichiers (>40MB)
|
||||||
|
Timeout 3600
|
||||||
|
KeepAlive On
|
||||||
|
KeepAliveTimeout 300
|
||||||
|
MaxKeepAliveRequests 200
|
||||||
|
|
||||||
|
<Directory /var/www/html/>
|
||||||
|
Options FollowSymLinks MultiViews
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
|
||||||
|
<IfModule mod_dav.c>
|
||||||
|
Dav off
|
||||||
|
</IfModule>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# Headers de sécurité (si non gérés par Traefik)
|
||||||
|
<IfModule mod_headers.c>
|
||||||
|
# HSTS sera géré par Traefik
|
||||||
|
# Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
|
||||||
|
|
||||||
|
# Autres headers de sécurité
|
||||||
|
Header always set Referrer-Policy "no-referrer-when-downgrade"
|
||||||
|
Header always set X-Content-Type-Options "nosniff"
|
||||||
|
Header always set X-Frame-Options "SAMEORIGIN"
|
||||||
|
Header always set X-XSS-Protection "1; mode=block"
|
||||||
|
Header always set X-Robots-Tag "noindex, nofollow"
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Logs avec IP réelle (pas l'IP de Traefik)
|
||||||
|
<IfModule mod_remoteip.c>
|
||||||
|
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
|
||||||
|
</IfModule>
|
||||||
24
cron/Dockerfile
Normal file
24
cron/Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Installer les dépendances nécessaires
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
docker-cli \
|
||||||
|
docker-cli-compose \
|
||||||
|
bash \
|
||||||
|
tzdata
|
||||||
|
|
||||||
|
# Configurer le fuseau horaire
|
||||||
|
ENV TZ=Europe/Paris
|
||||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
|
# Copier le fichier crontab
|
||||||
|
COPY crontab /etc/crontabs/root
|
||||||
|
|
||||||
|
# Copier le script d'entrée
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
RUN chmod +x /entrypoint.sh
|
||||||
|
|
||||||
|
# Créer le répertoire pour les logs
|
||||||
|
RUN mkdir -p /logs
|
||||||
|
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
147
cron/README.md
Normal file
147
cron/README.md
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
# Backup Automatique Nextcloud
|
||||||
|
|
||||||
|
Ce dossier contient la configuration pour les backups automatiques via un container Docker dédié.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Le service `backup-cron` est un container Alpine Linux léger qui exécute des tâches planifiées:
|
||||||
|
|
||||||
|
- **Image**: Alpine Linux avec Docker CLI et docker-compose
|
||||||
|
- **Fuseau horaire**: Europe/Paris (configurable via `TZ`)
|
||||||
|
- **Montages**:
|
||||||
|
- `/project`: Projet complet (scripts, config, etc.)
|
||||||
|
- `/var/run/docker.sock`: Socket Docker pour exécuter docker-compose
|
||||||
|
- `/logs`: Répertoire des logs partagé avec l'hôte
|
||||||
|
|
||||||
|
## Planning par défaut
|
||||||
|
|
||||||
|
| Tâche | Fréquence | Heure | Description |
|
||||||
|
|-------|-----------|-------|-------------|
|
||||||
|
| Backup | Quotidien | 5h00 | Backup complet (DB + fichiers) |
|
||||||
|
| Health check | Quotidien | 6h00 | Vérification après backup |
|
||||||
|
| Nettoyage | Hebdomadaire | Dimanche 3h00 | Suppression logs > 30 jours |
|
||||||
|
|
||||||
|
## Utilisation
|
||||||
|
|
||||||
|
### Démarrer le service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build et démarrage
|
||||||
|
docker-compose up -d backup-cron
|
||||||
|
|
||||||
|
# Ou reconstruire si modifié
|
||||||
|
docker-compose up -d --build backup-cron
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vérifier le statut
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via Makefile
|
||||||
|
make cron-status
|
||||||
|
|
||||||
|
# Ou directement
|
||||||
|
docker-compose ps backup-cron
|
||||||
|
docker-compose exec backup-cron cat /etc/crontabs/root
|
||||||
|
```
|
||||||
|
|
||||||
|
### Consulter les logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via Makefile
|
||||||
|
make cron-logs
|
||||||
|
|
||||||
|
# Ou directement
|
||||||
|
tail -f logs/cron_backup.log
|
||||||
|
tail -f logs/cron_health.log
|
||||||
|
tail -f logs/cron_clean.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tester manuellement
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Exécuter un backup immédiatement
|
||||||
|
docker-compose exec backup-cron /bin/bash -c "cd /project && bash scripts/backup.sh"
|
||||||
|
|
||||||
|
# Vérifier l'heure du container
|
||||||
|
docker-compose exec backup-cron date
|
||||||
|
```
|
||||||
|
|
||||||
|
## Personnalisation
|
||||||
|
|
||||||
|
### Modifier le planning
|
||||||
|
|
||||||
|
Éditez `cron/crontab` puis reconstruisez:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Format cron: minute hour day month weekday command
|
||||||
|
# Exemple: backup toutes les 6 heures
|
||||||
|
0 */6 * * * cd /project && bash scripts/backup.sh >> /logs/cron_backup.log 2>&1
|
||||||
|
|
||||||
|
# Reconstruire
|
||||||
|
docker-compose up -d --build backup-cron
|
||||||
|
```
|
||||||
|
|
||||||
|
### Changer le fuseau horaire
|
||||||
|
|
||||||
|
Modifiez `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- TZ=America/New_York # ou autre fuseau
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sécurité
|
||||||
|
|
||||||
|
⚠️ **Important**: Le container a accès au socket Docker (`/var/run/docker.sock`), ce qui lui permet d'exécuter des commandes docker-compose. Cela est nécessaire pour les backups mais donne des privilèges élevés.
|
||||||
|
|
||||||
|
**Bonnes pratiques**:
|
||||||
|
- N'exposez pas ce service sur le réseau externe
|
||||||
|
- Gardez les scripts de backup en lecture seule si possible
|
||||||
|
- Surveillez les logs régulièrement
|
||||||
|
- Limitez les ressources du container si nécessaire
|
||||||
|
|
||||||
|
## Dépannage
|
||||||
|
|
||||||
|
### Le container ne démarre pas
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier les logs
|
||||||
|
docker-compose logs backup-cron
|
||||||
|
|
||||||
|
# Reconstruire from scratch
|
||||||
|
docker-compose build --no-cache backup-cron
|
||||||
|
docker-compose up -d backup-cron
|
||||||
|
```
|
||||||
|
|
||||||
|
### Les tâches ne s'exécutent pas
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier que crond tourne
|
||||||
|
docker-compose exec backup-cron ps aux | grep crond
|
||||||
|
|
||||||
|
# Vérifier le crontab
|
||||||
|
docker-compose exec backup-cron cat /etc/crontabs/root
|
||||||
|
|
||||||
|
# Vérifier l'heure du container
|
||||||
|
docker-compose exec backup-cron date
|
||||||
|
```
|
||||||
|
|
||||||
|
### Problèmes de permissions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Le container doit pouvoir écrire dans ./backups et ./logs
|
||||||
|
chmod 755 backups logs
|
||||||
|
|
||||||
|
# Vérifier les montages
|
||||||
|
docker-compose exec backup-cron ls -la /project/backups
|
||||||
|
```
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
|
||||||
|
Tous les logs sont stockés dans `./logs/`:
|
||||||
|
|
||||||
|
- `cron_backup.log`: Sorties des backups quotidiens
|
||||||
|
- `cron_health.log`: Résultats des health checks
|
||||||
|
- `cron_clean.log`: Logs de nettoyage hebdomadaire
|
||||||
|
|
||||||
|
Les logs sont automatiquement nettoyés après 30 jours.
|
||||||
11
cron/crontab
Normal file
11
cron/crontab
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Nextcloud Docker - Tâches automatisées
|
||||||
|
# Format: minute hour day month weekday command
|
||||||
|
|
||||||
|
# Backup quotidien à 5h00 du matin (heure de Paris)
|
||||||
|
0 5 * * * cd /project && bash scripts/backup.sh >> /logs/cron_backup.log 2>&1
|
||||||
|
|
||||||
|
# Health check quotidien à 6h00 (après le backup)
|
||||||
|
0 6 * * * cd /project && bash scripts/check-health.sh >> /logs/cron_health.log 2>&1
|
||||||
|
|
||||||
|
# Nettoyage hebdomadaire le dimanche à 3h00
|
||||||
|
0 3 * * 0 cd /project && bash scripts/clean-old-logs.sh >> /logs/cron_clean.log 2>&1
|
||||||
18
cron/entrypoint.sh
Executable file
18
cron/entrypoint.sh
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "========================================="
|
||||||
|
echo "Nextcloud Backup Cron Container"
|
||||||
|
echo "========================================="
|
||||||
|
echo "Fuseau horaire: ${TZ:-UTC}"
|
||||||
|
echo "Heure actuelle: $(date)"
|
||||||
|
echo ""
|
||||||
|
echo "Tâches programmées:"
|
||||||
|
cat /etc/crontabs/root | grep -v "^#" | grep -v "^$"
|
||||||
|
echo ""
|
||||||
|
echo "Logs disponibles dans /logs/"
|
||||||
|
echo "========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Démarrer crond en mode foreground
|
||||||
|
exec crond -f -l 2
|
||||||
@@ -13,3 +13,6 @@ binlog_format = ROW
|
|||||||
|
|
||||||
# Connections
|
# Connections
|
||||||
max_connections = 200
|
max_connections = 200
|
||||||
|
|
||||||
|
# Gros fichiers - augmenter la taille max des paquets
|
||||||
|
max_allowed_packet = 1G
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
services:
|
services:
|
||||||
nextcloud:
|
nextcloud:
|
||||||
image: nextcloud:latest
|
build: .
|
||||||
container_name: nextcloud
|
image: nextcloud-custom:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:8888:80"
|
- "127.0.0.1:8888:80"
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/var/www/html
|
- ./data:/var/www/html
|
||||||
|
- ./apache/nextcloud.conf:/etc/apache2/conf-enabled/nextcloud.conf:ro
|
||||||
|
- ./apache/mpm_prefork.conf:/etc/apache2/mods-available/mpm_prefork.conf:ro
|
||||||
|
- ./logs/apache:/var/log/apache2
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
tag: "nextcloud"
|
||||||
environment:
|
environment:
|
||||||
# Database
|
# Database
|
||||||
- MYSQL_HOST=db
|
- MYSQL_HOST=db
|
||||||
@@ -15,21 +24,25 @@ services:
|
|||||||
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||||
# Domaine
|
# Domaine
|
||||||
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN}
|
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN}
|
||||||
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-172.16.0.0/12}
|
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
|
||||||
- OVERWRITEPROTOCOL=https
|
- OVERWRITEPROTOCOL=${OVERWRITE_PROTOCOL:-http}
|
||||||
- OVERWRITEHOST=${NEXTCLOUD_DOMAIN}
|
- OVERWRITEHOST=${OVERWRITE_HOST:-}
|
||||||
- OVERWRITECLIURL=https://${NEXTCLOUD_DOMAIN}
|
- OVERWRITECLIURL=${OVERWRITE_CLI_URL:-}
|
||||||
# Redis
|
# Redis
|
||||||
- REDIS_HOST=redis
|
- REDIS_HOST=redis
|
||||||
- REDIS_HOST_PASSWORD=${REDIS_HOST_PASSWORD}
|
- REDIS_HOST_PASSWORD=${REDIS_HOST_PASSWORD}
|
||||||
# PHP
|
# PHP
|
||||||
- PHP_MEMORY_LIMIT=4096M
|
- PHP_MEMORY_LIMIT=4096M
|
||||||
- PHP_UPLOAD_MAX_FILESIZE=2G
|
- PHP_UPLOAD_MAX_FILESIZE=10G
|
||||||
- PHP_POST_MAX_SIZE=2G
|
- PHP_POST_MAX_SIZE=10G
|
||||||
- PHP_MAX_EXECUTION_TIME=1800
|
- PHP_MAX_EXECUTION_TIME=7200
|
||||||
- PHP_MAX_INPUT_TIME=1800
|
- PHP_MAX_INPUT_TIME=7200
|
||||||
|
# - PHP_UPLOAD_MAX_FILESIZE=1024G
|
||||||
|
# - PHP_POST_MAX_SIZE=1024G
|
||||||
|
# - PHP_MAX_EXECUTION_TIME=86400
|
||||||
|
# - PHP_MAX_INPUT_TIME=86400
|
||||||
# Apache
|
# Apache
|
||||||
- APACHE_BODY_LIMIT=2147483648
|
- APACHE_BODY_LIMIT=0
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost/status.php"]
|
test: ["CMD", "curl", "-f", "http://localhost/status.php"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
@@ -43,16 +56,32 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- nextcloud-net
|
- nextcloud-net
|
||||||
- traefik-net
|
- traefik-net
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
# Router configuration
|
||||||
|
- "traefik.http.routers.cloud.rule=Host(`${NEXTCLOUD_DOMAIN}`)"
|
||||||
|
- "traefik.http.routers.cloud.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.cloud.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.routers.cloud.middlewares=nextcloud-headers,nextcloud-redirect"
|
||||||
|
# Service configuration
|
||||||
|
- "traefik.http.services.cloud.loadbalancer.server.port=80"
|
||||||
|
- "traefik.http.services.cloud.loadbalancer.serverstransport=nextcloud-transport"
|
||||||
|
# Middleware: Headers
|
||||||
|
- "traefik.http.middlewares.nextcloud-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
|
||||||
|
- "traefik.http.middlewares.nextcloud-headers.headers.customresponseheaders.Strict-Transport-Security=max-age=15552000"
|
||||||
|
# Middleware: Redirect pour CalDAV/CardDAV
|
||||||
|
- "traefik.http.middlewares.nextcloud-redirect.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav"
|
||||||
|
- "traefik.http.middlewares.nextcloud-redirect.redirectregex.replacement=https://$$1/remote.php/dav/"
|
||||||
|
- "traefik.http.middlewares.nextcloud-redirect.redirectregex.permanent=true"
|
||||||
redis:
|
redis:
|
||||||
image: redis:alpine
|
image: redis:alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: redis-server --requirepass ${REDIS_HOST_PASSWORD} --maxmemory 512mb --maxmemory-policy allkeys-lru
|
command: redis-server --requirepass ${REDIS_HOST_PASSWORD} --maxmemory 2gb --maxmemory-policy allkeys-lru
|
||||||
networks:
|
networks:
|
||||||
- nextcloud-net
|
- nextcloud-net
|
||||||
|
|
||||||
cron:
|
cron:
|
||||||
image: nextcloud:latest
|
image: nextcloud-custom:latest
|
||||||
restart: always
|
restart: always
|
||||||
volumes_from:
|
volumes_from:
|
||||||
- nextcloud
|
- nextcloud
|
||||||
@@ -64,6 +93,28 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- nextcloud-net
|
- nextcloud-net
|
||||||
|
|
||||||
|
backup-cron:
|
||||||
|
build: ./cron
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
# Monter le projet complet pour accéder aux scripts
|
||||||
|
- .:/project
|
||||||
|
# Monter Docker socket pour exécuter les commandes docker-compose
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
# Partager les volumes avec nextcloud pour les backups
|
||||||
|
- ./data:/var/www/html
|
||||||
|
- ./db:/var/lib/mysql
|
||||||
|
- ./backups:/project/backups
|
||||||
|
- ./logs:/logs
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Paris
|
||||||
|
- COMPOSE_PROJECT_NAME
|
||||||
|
depends_on:
|
||||||
|
- nextcloud
|
||||||
|
- db
|
||||||
|
networks:
|
||||||
|
- nextcloud-net
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: mariadb:10.11
|
image: mariadb:10.11
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -71,7 +122,7 @@ services:
|
|||||||
- ./db:/var/lib/mysql
|
- ./db:/var/lib/mysql
|
||||||
- ./db-config/my.cnf:/etc/mysql/conf.d/custom.cnf:ro
|
- ./db-config/my.cnf:/etc/mysql/conf.d/custom.cnf:ro
|
||||||
environment:
|
environment:
|
||||||
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_USER}
|
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||||
- MYSQL_DATABASE=nextcloud
|
- MYSQL_DATABASE=nextcloud
|
||||||
- MYSQL_USER=${MYSQL_USER}
|
- MYSQL_USER=${MYSQL_USER}
|
||||||
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||||
|
|||||||
282
scripts/backup.sh
Normal file → Executable file
282
scripts/backup.sh
Normal file → Executable file
@@ -1,75 +1,267 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# scripts/backup.sh - Backup complet Nextcloud
|
# scripts/backup.sh - Backup complet Nextcloud
|
||||||
|
|
||||||
set -e
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Variables globales
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Charger .env en premier
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
echo "ERROR: Fichier .env introuvable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1091
|
||||||
source .env
|
source .env
|
||||||
|
set +a
|
||||||
|
|
||||||
BACKUP_DIR="${BACKUP_DESTINATION:-./backups}"
|
# Configuration
|
||||||
DATE=$(date +%Y%m%d_%H%M%S)
|
DATE=$(date +%Y%m%d_%H%M%S)
|
||||||
|
LOCK_FILE="/tmp/nextcloud_backup.lock"
|
||||||
|
LOG_DIR="./logs"
|
||||||
|
LOG_FILE="$PROJECT_ROOT/logs/backup_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
BACKUP_DIR="${BACKUP_DESTINATION:-./backups}"
|
||||||
|
BACKUP_RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}"
|
||||||
BACKUP_NAME="nextcloud_backup_$DATE"
|
BACKUP_NAME="nextcloud_backup_$DATE"
|
||||||
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
|
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
|
||||||
|
MAINTENANCE_ENABLED=false
|
||||||
|
|
||||||
echo "🔧 Démarrage du backup: $BACKUP_NAME"
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# Charger les fonctions communes (log avec couleurs)
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
if [ -z "${MYSQL_DATABASE:-}" ] || [ -z "${MYSQL_USER:-}" ] || [ -z "${MYSQL_PASSWORD:-}" ]; then
|
||||||
|
log "ERROR" "Variables MysqlSQL non définies dans .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier qu'un backup n'est pas déjà en cours
|
||||||
|
if [ -f "$LOCK_FILE" ]; then
|
||||||
|
log "ERROR" "Une sauvegarde est déjà en cours. Si aucune sauvegarde n'est en cours, supprimez le fichier: $LOCK_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch "$LOCK_FILE"
|
||||||
|
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# Fonction de nettoyage en cas d'erreur
|
||||||
|
cleanup() {
|
||||||
|
local exit_code=$?
|
||||||
|
|
||||||
|
if [ "$exit_code" -ne 0 ]; then
|
||||||
|
log "ERROR" "Erreur détectée (code: $exit_code), nettoyage..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Désactiver le mode maintenance si activé
|
||||||
|
if [ "$MAINTENANCE_ENABLED" = true ]; then
|
||||||
|
log "INFO" "Désactivation du mode maintenance..."
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nettoyer le backup partiel
|
||||||
|
if [ -d "$BACKUP_PATH" ]; then
|
||||||
|
log "INFO" "Nettoyage du backup partiel..."
|
||||||
|
rm -rf "${BACKUP_PATH:?}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Supprimer le lock
|
||||||
|
rm -f "$LOCK_FILE"
|
||||||
|
|
||||||
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
|
log "SUCCESS" "Backup terminé avec succès"
|
||||||
|
else
|
||||||
|
log "ERROR" "Backup échoué avec code: $exit_code"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
log "INFO" "=== Démarrage du backup: $BACKUP_NAME ==="
|
||||||
|
log "INFO" "Log file: $LOG_FILE"
|
||||||
|
|
||||||
|
# Vérifier l'espace disque disponible
|
||||||
|
log "INFO" "Vérification de l'espace disque..."
|
||||||
|
|
||||||
|
# Calculer l'espace requis (taille data + db avec 20% de marge)
|
||||||
|
# Calculer depuis le container avec les mêmes exclusions que le backup
|
||||||
|
log "INFO" "Calcul de la taille réelle (avec exclusions)..."
|
||||||
|
DATA_SIZE=$(docker-compose exec -T nextcloud du -sb \
|
||||||
|
--exclude='appdata_*/preview' \
|
||||||
|
--exclude='*/cache' \
|
||||||
|
--exclude='*/thumbnails' \
|
||||||
|
/var/www/html/data 2>/dev/null | awk '{print $1}' || echo "0")
|
||||||
|
|
||||||
|
# Note: On n'inclut pas la DB car mysqldump est beaucoup plus petit que les fichiers MySQL bruts
|
||||||
|
# Typiquement: fichiers MySQL = 650MB → dump SQL = 500KB (compression ~99%)
|
||||||
|
# On ajoute juste 10MB fixe pour DB + config + apps (généralement < 1MB au final)
|
||||||
|
DB_ESTIMATE=10485760 # 10MB
|
||||||
|
|
||||||
|
# Additionner avec 20% de marge
|
||||||
|
REQUIRED_SPACE=$(echo "$DATA_SIZE + $DB_ESTIMATE" | awk '{total=$1+$3; print int(total*1.2)}')
|
||||||
|
|
||||||
|
if [ -z "$REQUIRED_SPACE" ] || [ "$REQUIRED_SPACE" = "0" ]; then
|
||||||
|
log "WARN" "Impossible de calculer l'espace requis, estimation à 500MB"
|
||||||
|
REQUIRED_SPACE=500000000 # 500MB par défaut (plus réaliste que 2GB)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Obtenir l'espace disponible (enlever les espaces/newlines)
|
||||||
|
# Utiliser -P pour format POSIX (garantit une ligne par système de fichiers)
|
||||||
|
AVAILABLE_SPACE=$(df -P -B1 "$BACKUP_DIR" | awk 'NR==2 {print $4}' | tr -d '[:space:]')
|
||||||
|
if [ -z "$AVAILABLE_SPACE" ]; then
|
||||||
|
log "ERROR" "Impossible de déterminer l'espace disque disponible"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Calculer estimation avec compression
|
||||||
|
# Note: Nextcloud a beaucoup de fichiers déjà compressés (images, PDFs)
|
||||||
|
# donc la compression gzip est peu efficace (~30% au lieu de 90%)
|
||||||
|
if [ "$REQUIRED_SPACE" -gt 0 ] 2>/dev/null; then
|
||||||
|
ESTIMATED_COMPRESSED=$((REQUIRED_SPACE * 7 / 10)) # 70% de la taille (30% de compression)
|
||||||
|
log "INFO" "Espace requis (non compressé + 20%): $(numfmt --to=iec-i --suffix=B "$REQUIRED_SPACE" 2>/dev/null || echo "$REQUIRED_SPACE bytes")"
|
||||||
|
log "INFO" "Espace estimé après compression: $(numfmt --to=iec-i --suffix=B "$ESTIMATED_COMPRESSED" 2>/dev/null || echo "$ESTIMATED_COMPRESSED bytes")"
|
||||||
|
else
|
||||||
|
log "INFO" "Espace requis: Impossible à calculer (utilisation du fallback)"
|
||||||
|
fi
|
||||||
|
log "INFO" "Espace disponible: $(numfmt --to=iec-i --suffix=B "$AVAILABLE_SPACE" 2>/dev/null || echo "$AVAILABLE_SPACE bytes")"
|
||||||
|
|
||||||
|
# Comparaison sécurisée avec validation
|
||||||
|
if [ "$AVAILABLE_SPACE" -lt "$REQUIRED_SPACE" ] 2>/dev/null; then
|
||||||
|
log "ERROR" "Espace disque insuffisant"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Créer le dossier de backup
|
# Créer le dossier de backup
|
||||||
mkdir -p "$BACKUP_PATH"
|
mkdir -p "$BACKUP_PATH"
|
||||||
|
|
||||||
# 1. Activer le mode maintenance
|
# 1. Activer le mode maintenance
|
||||||
echo "⏸️ Activation du mode maintenance..."
|
log "INFO" "Activation du mode maintenance..."
|
||||||
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --on
|
if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --on 2>>"$LOG_FILE"; then
|
||||||
|
MAINTENANCE_ENABLED=true
|
||||||
|
log "INFO" "Mode maintenance activé"
|
||||||
|
else
|
||||||
|
log "ERROR" "Impossible d'activer le mode maintenance"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# 2. Backup de la base de données
|
# 2. Backup de la base de données
|
||||||
echo "💾 Backup de la base de données..."
|
log "INFO" "Backup de la base de données..."
|
||||||
docker-compose exec -T db mysqldump \
|
START_TIME=$(date +%s)
|
||||||
-u"$MYSQL_USER" \
|
if ! docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysqldump \
|
||||||
-p"$MYSQL_PASSWORD" \
|
-u\"\$MYSQL_USER\" \
|
||||||
"$MYSQL_DATABASE" \
|
\"\$MYSQL_DATABASE\" \
|
||||||
--single-transaction \
|
--single-transaction \
|
||||||
--quick \
|
--quick \
|
||||||
--lock-tables=false \
|
--lock-tables=false" >"$BACKUP_PATH/database.sql" 2>>"$LOG_FILE"; then
|
||||||
> "$BACKUP_PATH/database.sql"
|
log "ERROR" "Erreur lors du backup de la base de données"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
END_TIME=$(date +%s)
|
||||||
|
DB_SIZE=$(du -h "$BACKUP_PATH/database.sql" | cut -f1)
|
||||||
|
log "INFO" "Base de données sauvegardée: $DB_SIZE ($((END_TIME - START_TIME))s)"
|
||||||
|
|
||||||
# 3. Backup des fichiers de config
|
# 3. Backup des fichiers de config
|
||||||
echo "⚙️ Backup de la configuration..."
|
log "INFO" "Backup de la configuration..."
|
||||||
tar -czf "$BACKUP_PATH/config.tar.gz" \
|
START_TIME=$(date +%s)
|
||||||
-C ./data/config .
|
if ! docker-compose exec -T -u www-data nextcloud tar -czf - -C /var/www/html/config . >"$BACKUP_PATH/config.tar.gz" 2>>"$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors du backup de la configuration"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
END_TIME=$(date +%s)
|
||||||
|
CONFIG_SIZE=$(du -h "$BACKUP_PATH/config.tar.gz" | cut -f1)
|
||||||
|
log "INFO" "Configuration sauvegardée: $CONFIG_SIZE ($((END_TIME - START_TIME))s)"
|
||||||
|
|
||||||
# 4. Backup des données utilisateurs (optionnel, peut être énorme)
|
# 4. Backup des données utilisateurs
|
||||||
echo "📁 Backup des données utilisateurs..."
|
log "INFO" "Backup des données utilisateurs..."
|
||||||
# Pour un backup incrémental, utilisez rsync
|
START_TIME=$(date +%s)
|
||||||
rsync -a --info=progress2 \
|
if ! docker-compose exec -T -u www-data nextcloud tar -czf - \
|
||||||
./data/data/ \
|
-C /var/www/html/data \
|
||||||
"$BACKUP_PATH/data/" \
|
--exclude='appdata_*/preview' \
|
||||||
--exclude 'appdata_*/preview' \
|
--exclude='*/cache' \
|
||||||
--exclude '*/cache' \
|
--exclude='*/thumbnails' \
|
||||||
--exclude '*/thumbnails'
|
. >"$BACKUP_PATH/data.tar.gz" 2>>"$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors du backup des données"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
END_TIME=$(date +%s)
|
||||||
|
DATA_SIZE=$(du -h "$BACKUP_PATH/data.tar.gz" | cut -f1)
|
||||||
|
log "INFO" "Données sauvegardées: $DATA_SIZE ($((END_TIME - START_TIME))s)"
|
||||||
|
|
||||||
# Ou pour un tar compressé (long):
|
# 5. Backup des apps personnalisées
|
||||||
# tar -czf "$BACKUP_PATH/data.tar.gz" \
|
log "INFO" "Backup des apps personnalisées..."
|
||||||
# --exclude='appdata_*/preview' \
|
if docker-compose exec -T nextcloud [ -d /var/www/html/custom_apps ] 2>>"$LOG_FILE"; then
|
||||||
# -C ./data/data .
|
if docker-compose exec -T -u www-data nextcloud tar -czf - \
|
||||||
|
-C /var/www/html/custom_apps . >"$BACKUP_PATH/apps.tar.gz" 2>>"$LOG_FILE"; then
|
||||||
# 5. Backup des apps
|
APPS_SIZE=$(du -h "$BACKUP_PATH/apps.tar.gz" | cut -f1)
|
||||||
echo "📦 Backup des apps personnalisées..."
|
log "INFO" "Apps sauvegardées: $APPS_SIZE"
|
||||||
if [ -d "./data/custom_apps" ]; then
|
else
|
||||||
tar -czf "$BACKUP_PATH/apps.tar.gz" \
|
log "WARN" "Erreur lors du backup des apps personnalisées"
|
||||||
-C ./data/custom_apps .
|
fi
|
||||||
|
else
|
||||||
|
log "INFO" "Pas d'apps personnalisées à sauvegarder"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 6. Désactiver le mode maintenance
|
# 6. Désactiver le mode maintenance
|
||||||
echo "▶️ Désactivation du mode maintenance..."
|
log "INFO" "Désactivation du mode maintenance..."
|
||||||
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off
|
if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE"; then
|
||||||
|
MAINTENANCE_ENABLED=false
|
||||||
|
log "INFO" "Mode maintenance désactivé"
|
||||||
|
else
|
||||||
|
log "WARN" "Impossible de désactiver le mode maintenance"
|
||||||
|
fi
|
||||||
|
|
||||||
# 7. Créer une archive complète
|
# 7. Créer une archive complète
|
||||||
echo "🗜️ Compression finale..."
|
log "INFO" "Compression finale..."
|
||||||
cd "$BACKUP_DIR"
|
START_TIME=$(date +%s)
|
||||||
tar -czf "$BACKUP_NAME.tar.gz" "$BACKUP_NAME/"
|
if ! tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" -C "$BACKUP_DIR" "$BACKUP_NAME/" 2>>"$LOG_FILE"; then
|
||||||
rm -rf "$BACKUP_NAME"
|
log "ERROR" "Erreur lors de la compression"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
END_TIME=$(date +%s)
|
||||||
|
ARCHIVE_SIZE=$(du -h "$BACKUP_DIR/$BACKUP_NAME.tar.gz" | cut -f1)
|
||||||
|
log "INFO" "Archive créée: $ARCHIVE_SIZE ($((END_TIME - START_TIME))s)"
|
||||||
|
|
||||||
# 8. Nettoyer les vieux backups
|
# 8. Générer le checksum SHA256
|
||||||
echo "🧹 Nettoyage des backups > ${BACKUP_RETENTION_DAYS:-30} jours..."
|
log "INFO" "Génération du checksum SHA256..."
|
||||||
find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -mtime +${BACKUP_RETENTION_DAYS:-30} -delete
|
if cd "$BACKUP_DIR" && sha256sum "$BACKUP_NAME.tar.gz" >"$BACKUP_NAME.tar.gz.sha256"; then
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
CHECKSUM=$(cut -d' ' -f1 "$BACKUP_DIR/$BACKUP_NAME.tar.gz.sha256")
|
||||||
|
else
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
log "WARN" "Impossible de générer le checksum"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "✅ Backup terminé: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
|
# Supprimer le dossier temporaire après compression réussie
|
||||||
du -h "$BACKUP_DIR/$BACKUP_NAME.tar.gz"
|
rm -rf "${BACKUP_PATH:?}"
|
||||||
|
|
||||||
|
# 9. Nettoyer les vieux backups
|
||||||
|
log "INFO" "Nettoyage des backups > $BACKUP_RETENTION_DAYS jours..."
|
||||||
|
DELETED_COUNT=0
|
||||||
|
while IFS= read -r -d '' file; do
|
||||||
|
CHECKSUM_FILE="${file}.sha256"
|
||||||
|
log "INFO" "Suppression: $(basename "$file")"
|
||||||
|
rm -f "$file" "$CHECKSUM_FILE" 2>>"$LOG_FILE" || true
|
||||||
|
DELETED_COUNT=$((DELETED_COUNT + 1))
|
||||||
|
done < <(find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f -mtime +"$BACKUP_RETENTION_DAYS" -print0 2>/dev/null || true)
|
||||||
|
|
||||||
|
if [ "$DELETED_COUNT" -gt 0 ]; then
|
||||||
|
log "INFO" "$DELETED_COUNT ancien(s) backup(s) supprimé(s)"
|
||||||
|
else
|
||||||
|
log "INFO" "Aucun ancien backup à supprimer"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 10. Statistiques finales
|
||||||
|
log "INFO" "=== Statistiques du backup ==="
|
||||||
|
log "INFO" "Archive: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
|
||||||
|
log "INFO" "Taille: $ARCHIVE_SIZE"
|
||||||
|
log "INFO" "Checksum: ${CHECKSUM:-N/A}"
|
||||||
|
log "INFO" "Rétention: $BACKUP_RETENTION_DAYS jours"
|
||||||
|
log "INFO" "Backups disponibles: $(find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f 2>/dev/null | wc -l)"
|
||||||
|
|||||||
283
scripts/check-health.sh
Executable file
283
scripts/check-health.sh
Executable file
@@ -0,0 +1,283 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/check-health.sh - Vérification complète de la santé du système
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Variables globales
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Charger .env pour accéder aux variables (Redis password, etc.)
|
||||||
|
if [ -f .env ]; then
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source .env
|
||||||
|
set +a
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Charger les couleurs depuis common.sh
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
# Compteurs
|
||||||
|
CHECKS_PASSED=0
|
||||||
|
CHECKS_FAILED=0
|
||||||
|
CHECKS_WARNING=0
|
||||||
|
|
||||||
|
# Fonction de logging
|
||||||
|
check_ok() {
|
||||||
|
echo -e "${GREEN}✓${NC} $*"
|
||||||
|
CHECKS_PASSED=$((CHECKS_PASSED + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
check_fail() {
|
||||||
|
echo -e "${RED}✗${NC} $*"
|
||||||
|
CHECKS_FAILED=$((CHECKS_FAILED + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
check_warn() {
|
||||||
|
echo -e "${YELLOW}⚠${NC} $*"
|
||||||
|
CHECKS_WARNING=$((CHECKS_WARNING + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "=== Health Check Nextcloud ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 1. Vérifier que Docker est disponible
|
||||||
|
echo "▶ Vérifications système:"
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
check_ok "Docker installé: $(docker --version | head -1)"
|
||||||
|
else
|
||||||
|
check_fail "Docker non installé"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier Docker Compose
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
|
||||||
|
check_ok "Docker Compose v2 installé: $(docker compose version --short)"
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
check_warn "Docker Compose v1 installé (obsolète): $(docker-compose --version)"
|
||||||
|
else
|
||||||
|
check_fail "Docker Compose non installé"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 2. Vérifier les fichiers de configuration
|
||||||
|
echo "▶ Fichiers de configuration:"
|
||||||
|
if [ -f .env ]; then
|
||||||
|
check_ok "Fichier .env présent"
|
||||||
|
|
||||||
|
# Vérifier les mots de passe faibles
|
||||||
|
if grep -qE "(userpassword|rootpassword|redispassword)" .env 2>/dev/null; then
|
||||||
|
check_warn "Mots de passe faibles détectés dans .env - Changez-les!"
|
||||||
|
else
|
||||||
|
check_ok "Pas de mots de passe faibles détectés"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_fail "Fichier .env manquant"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f docker-compose.yml ]; then
|
||||||
|
check_ok "Fichier docker-compose.yml présent"
|
||||||
|
else
|
||||||
|
check_fail "Fichier docker-compose.yml manquant"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 3. Vérifier l'état des containers
|
||||||
|
echo "▶ État des containers:"
|
||||||
|
CONTAINERS=("nextcloud" "db" "redis" "cron")
|
||||||
|
for container in "${CONTAINERS[@]}"; do
|
||||||
|
if docker-compose ps "$container" 2>/dev/null | grep -q "Up"; then
|
||||||
|
check_ok "Container $container: actif"
|
||||||
|
else
|
||||||
|
check_fail "Container $container: inactif ou manquant"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 4. Vérifier Nextcloud
|
||||||
|
echo "▶ Application Nextcloud:"
|
||||||
|
if docker-compose exec -T nextcloud curl -f http://localhost/status.php >/dev/null 2>&1; then
|
||||||
|
check_ok "Nextcloud répond aux requêtes HTTP"
|
||||||
|
|
||||||
|
# Vérifier le statut via OCC
|
||||||
|
if STATUS=$(docker-compose exec -T -u www-data nextcloud php occ status 2>/dev/null); then
|
||||||
|
check_ok "Commande OCC accessible"
|
||||||
|
|
||||||
|
if echo "$STATUS" | grep -q "installed: true"; then
|
||||||
|
check_ok "Nextcloud installé"
|
||||||
|
else
|
||||||
|
check_fail "Nextcloud non installé"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "$STATUS" | grep -q "maintenance: false"; then
|
||||||
|
check_ok "Mode maintenance: désactivé"
|
||||||
|
else
|
||||||
|
check_warn "Mode maintenance: activé"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Afficher la version
|
||||||
|
VERSION=$(echo "$STATUS" | grep "versionstring:" | awk '{print $3}')
|
||||||
|
if [ -n "$VERSION" ]; then
|
||||||
|
check_ok "Version: $VERSION"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_fail "Impossible d'accéder aux commandes OCC"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_fail "Nextcloud ne répond pas"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 5. Vérifier la base de données
|
||||||
|
echo "▶ Base de données:"
|
||||||
|
if docker-compose exec -T db mysqladmin ping -h localhost --silent 2>/dev/null; then
|
||||||
|
check_ok "MariaDB répond"
|
||||||
|
|
||||||
|
# Tester la connexion MySQL (utilise les variables d'environnement du container)
|
||||||
|
if docker-compose exec -T db sh -c 'MYSQL_PWD="$MYSQL_PASSWORD" mysql -u"$MYSQL_USER" "$MYSQL_DATABASE" -e "SELECT 1"' >/dev/null 2>&1; then
|
||||||
|
check_ok "Connexion MySQL fonctionnelle"
|
||||||
|
else
|
||||||
|
check_fail "Impossible de se connecter à MySQL"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_fail "MariaDB ne répond pas"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 6. Vérifier Redis
|
||||||
|
echo "▶ Cache Redis:"
|
||||||
|
if [ -n "${REDIS_HOST_PASSWORD:-}" ]; then
|
||||||
|
if docker-compose exec -T redis redis-cli -a "$REDIS_HOST_PASSWORD" ping 2>/dev/null | grep -q "PONG"; then
|
||||||
|
check_ok "Redis répond (avec authentification)"
|
||||||
|
else
|
||||||
|
check_fail "Redis ne répond pas ou mot de passe incorrect"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if docker-compose exec -T redis redis-cli ping 2>/dev/null | grep -q "PONG"; then
|
||||||
|
check_ok "Redis répond (sans authentification)"
|
||||||
|
else
|
||||||
|
check_fail "Redis ne répond pas"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 7. Vérifier l'espace disque
|
||||||
|
echo "▶ Espace disque:"
|
||||||
|
DISK_USAGE=$(df -h . | awk 'NR==2 {print $5}' | sed 's/%//')
|
||||||
|
DISK_AVAIL=$(df -h . | awk 'NR==2 {print $4}')
|
||||||
|
|
||||||
|
if [ "$DISK_USAGE" -lt 80 ]; then
|
||||||
|
check_ok "Utilisation disque: ${DISK_USAGE}% (${DISK_AVAIL} disponible)"
|
||||||
|
elif [ "$DISK_USAGE" -lt 90 ]; then
|
||||||
|
check_warn "Utilisation disque: ${DISK_USAGE}% (${DISK_AVAIL} disponible) - Attention"
|
||||||
|
else
|
||||||
|
check_fail "Utilisation disque: ${DISK_USAGE}% (${DISK_AVAIL} disponible) - CRITIQUE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier la taille des données utilisateurs
|
||||||
|
if [ -d ./data/data ]; then
|
||||||
|
DATA_SIZE=$(du -sh ./data/data 2>/dev/null | cut -f1 || echo "")
|
||||||
|
if [ -z "$DATA_SIZE" ]; then
|
||||||
|
DATA_SIZE="N/A"
|
||||||
|
fi
|
||||||
|
check_ok "Taille des données utilisateurs: $DATA_SIZE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d ./db ]; then
|
||||||
|
DB_SIZE=$(du -sh ./db 2>/dev/null | cut -f1 || echo "")
|
||||||
|
if [ -z "$DB_SIZE" ]; then
|
||||||
|
DB_SIZE="N/A"
|
||||||
|
fi
|
||||||
|
check_ok "Taille de la base: $DB_SIZE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 8. Vérifier les backups
|
||||||
|
echo "▶ Backups:"
|
||||||
|
BACKUP_DIR="${BACKUP_DESTINATION:-./backups}"
|
||||||
|
if [ -d "$BACKUP_DIR" ]; then
|
||||||
|
BACKUP_COUNT=$(find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
if [ "$BACKUP_COUNT" -gt 0 ]; then
|
||||||
|
check_ok "$BACKUP_COUNT backup(s) disponible(s)"
|
||||||
|
|
||||||
|
# Trouver le backup le plus récent
|
||||||
|
LATEST_BACKUP=$(find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
||||||
|
if [ -n "$LATEST_BACKUP" ]; then
|
||||||
|
BACKUP_AGE=$(find "$LATEST_BACKUP" -mtime +1 2>/dev/null)
|
||||||
|
if [ -z "$BACKUP_AGE" ]; then
|
||||||
|
check_ok "Dernier backup: < 24h"
|
||||||
|
else
|
||||||
|
BACKUP_DAYS=$(find "$LATEST_BACKUP" -mtime +0 -printf '%Td' 2>/dev/null || echo "?")
|
||||||
|
if [ "$BACKUP_DAYS" -lt 7 ]; then
|
||||||
|
check_warn "Dernier backup: il y a ${BACKUP_DAYS} jour(s)"
|
||||||
|
else
|
||||||
|
check_fail "Dernier backup: il y a ${BACKUP_DAYS} jour(s) - Trop ancien!"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier le checksum
|
||||||
|
if [ -f "${LATEST_BACKUP}.sha256" ]; then
|
||||||
|
check_ok "Checksum présent pour le dernier backup"
|
||||||
|
else
|
||||||
|
check_warn "Pas de checksum pour le dernier backup"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_warn "Aucun backup trouvé dans $BACKUP_DIR"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_warn "Dossier de backup introuvable: $BACKUP_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 9. Vérifier les logs
|
||||||
|
echo "▶ Logs:"
|
||||||
|
if [ -d ./logs ]; then
|
||||||
|
LOG_COUNT=$(find ./logs -type f 2>/dev/null | wc -l)
|
||||||
|
check_ok "$LOG_COUNT fichier(s) de log"
|
||||||
|
|
||||||
|
LOGS_SIZE=$(du -sh ./logs 2>/dev/null | cut -f1 || echo "")
|
||||||
|
if [ -z "$LOGS_SIZE" ]; then
|
||||||
|
LOGS_SIZE="N/A"
|
||||||
|
fi
|
||||||
|
check_ok "Taille des logs: $LOGS_SIZE"
|
||||||
|
else
|
||||||
|
check_warn "Dossier de logs introuvable"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Résumé final
|
||||||
|
echo "=== Résumé ==="
|
||||||
|
echo -e "${GREEN}Réussi:${NC} $CHECKS_PASSED"
|
||||||
|
if [ "$CHECKS_WARNING" -gt 0 ]; then
|
||||||
|
echo -e "${YELLOW}Avertissements:${NC} $CHECKS_WARNING"
|
||||||
|
fi
|
||||||
|
if [ "$CHECKS_FAILED" -gt 0 ]; then
|
||||||
|
echo -e "${RED}Échecs:${NC} $CHECKS_FAILED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Code de sortie
|
||||||
|
if [ "$CHECKS_FAILED" -gt 0 ]; then
|
||||||
|
echo -e "${RED}❌ Système non sain - Des problèmes nécessitent votre attention${NC}"
|
||||||
|
exit 1
|
||||||
|
elif [ "$CHECKS_WARNING" -gt 0 ]; then
|
||||||
|
echo -e "${YELLOW}⚠ Système fonctionnel avec avertissements${NC}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✓ Système en bonne santé${NC}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
26
scripts/clean-old-logs.sh
Executable file
26
scripts/clean-old-logs.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/clean-old-logs.sh - Nettoyage automatique des vieux logs
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
LOG_DIR="./logs"
|
||||||
|
RETENTION_DAYS=30
|
||||||
|
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Nettoyage des logs > ${RETENTION_DAYS} jours..."
|
||||||
|
|
||||||
|
# Compter les fichiers avant nettoyage
|
||||||
|
BEFORE=$(find "$LOG_DIR" -type f -name "*.log" 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
# Supprimer les logs plus vieux que RETENTION_DAYS jours
|
||||||
|
DELETED=$(find "$LOG_DIR" -type f -name "*.log" -mtime +${RETENTION_DAYS} -delete -print 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
# Compter les fichiers après nettoyage
|
||||||
|
AFTER=$(find "$LOG_DIR" -type f -name "*.log" 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Fichiers supprimés: $DELETED"
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Fichiers restants: $AFTER"
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Nettoyage terminé"
|
||||||
33
scripts/common.sh
Normal file
33
scripts/common.sh
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# scripts/common.sh - Fonctions communes à tous les scripts
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Fonction de logging
|
||||||
|
log() {
|
||||||
|
local level="$1"
|
||||||
|
shift
|
||||||
|
local message="$*"
|
||||||
|
local timestamp
|
||||||
|
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
local color=""
|
||||||
|
case "$level" in
|
||||||
|
ERROR) color="${RED}" ;;
|
||||||
|
WARN) color="${YELLOW}" ;;
|
||||||
|
SUCCESS) color="${GREEN}" ;;
|
||||||
|
INFO) color="" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "[$timestamp] [$level] $message" >>"${LOG_FILE:-/tmp/script.log}"
|
||||||
|
|
||||||
|
if [ -t 1 ]; then
|
||||||
|
echo -e "${color}[$timestamp] [$level] $message${NC}"
|
||||||
|
else
|
||||||
|
echo "[$timestamp] [$level] $message"
|
||||||
|
fi
|
||||||
|
}
|
||||||
25
scripts/occ.sh
Normal file → Executable file
25
scripts/occ.sh
Normal file → Executable file
@@ -1,6 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# scripts/occ.sh - Wrapper pour commandes OCC
|
# scripts/occ.sh - Wrapper pour commandes OCC
|
||||||
|
|
||||||
set -e
|
set -euo pipefail
|
||||||
|
|
||||||
docker-compose exec -u www-data nextcloud php occ "$@"
|
# Détecter docker-compose v1 ou docker compose v2
|
||||||
|
DOCKER_COMPOSE=""
|
||||||
|
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
|
||||||
|
DOCKER_COMPOSE="docker compose"
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
DOCKER_COMPOSE="docker-compose"
|
||||||
|
else
|
||||||
|
echo "❌ Erreur: Ni 'docker compose' (v2) ni 'docker-compose' (v1) n'est disponible"
|
||||||
|
echo " Installez Docker Compose: https://docs.docker.com/compose/install/"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier que le container nextcloud est actif
|
||||||
|
if ! $DOCKER_COMPOSE ps nextcloud 2>/dev/null | grep -q "Up"; then
|
||||||
|
echo "❌ Erreur: Le container nextcloud n'est pas actif"
|
||||||
|
echo " Démarrez-le avec: make up"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Exécuter la commande OCC
|
||||||
|
# Le "$@" est sûr ici car il est passé directement à PHP OCC qui gère la validation
|
||||||
|
$DOCKER_COMPOSE exec -u www-data nextcloud php occ "$@"
|
||||||
|
|||||||
97
scripts/recover.sh
Executable file
97
scripts/recover.sh
Executable file
@@ -0,0 +1,97 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# scripts/recover.sh - Script de récupération après erreur
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Variables globales
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Configuration des logs
|
||||||
|
LOG_DIR="./logs"
|
||||||
|
LOG_FILE="$PROJECT_ROOT/logs/recover_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# Charger les fonctions communes (log avec couleurs)
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
log "INFO" "=== Script de récupération Nextcloud ==="
|
||||||
|
log "INFO" "Log file: $LOG_FILE"
|
||||||
|
|
||||||
|
# 1. Arrêter tous les conteneurs
|
||||||
|
log "INFO" "Arrêt de tous les conteneurs..."
|
||||||
|
if docker-compose down --remove-orphans 2>>"$LOG_FILE"; then
|
||||||
|
log "INFO" "Conteneurs arrêtés"
|
||||||
|
else
|
||||||
|
log "WARN" "Erreur lors de l'arrêt normal, tentative de force..."
|
||||||
|
docker-compose kill 2>>"$LOG_FILE" || true
|
||||||
|
docker-compose rm -f 2>>"$LOG_FILE" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Nettoyer les conteneurs orphelins
|
||||||
|
log "INFO" "Nettoyage des conteneurs orphelins..."
|
||||||
|
docker container prune -f 2>>"$LOG_FILE" || log "WARN" "Impossible de nettoyer les conteneurs"
|
||||||
|
|
||||||
|
# 3. Redémarrer les services
|
||||||
|
log "INFO" "Redémarrage des services..."
|
||||||
|
if ! docker-compose up -d 2>>"$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors du redémarrage"
|
||||||
|
log "ERROR" "Vérifiez les logs: docker-compose logs"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Attendre que Nextcloud soit prêt
|
||||||
|
log "INFO" "Attente du démarrage de Nextcloud (max 2 minutes)..."
|
||||||
|
for i in {1..120}; do
|
||||||
|
if docker-compose exec -T nextcloud curl -f http://localhost/status.php >/dev/null 2>&1; then
|
||||||
|
log "INFO" "Nextcloud prêt (${i}s)"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ "$i" -eq 120 ]; then
|
||||||
|
log "ERROR" "Timeout: Nextcloud n'est pas prêt après 2 minutes"
|
||||||
|
log "ERROR" "Logs des conteneurs:"
|
||||||
|
docker-compose logs --tail=50 nextcloud 2>&1 | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# 5. Désactiver le mode maintenance
|
||||||
|
log "INFO" "Désactivation du mode maintenance..."
|
||||||
|
if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE"; then
|
||||||
|
log "INFO" "Mode maintenance désactivé"
|
||||||
|
else
|
||||||
|
log "WARN" "Impossible de désactiver le mode maintenance"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 6. Vérifier le statut
|
||||||
|
log "INFO" "Statut final:"
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ status 2>&1 | tee -a "$LOG_FILE" || log "WARN" "Impossible d'obtenir le statut"
|
||||||
|
|
||||||
|
# 7. Suggérer les prochaines étapes
|
||||||
|
log "INFO" "=== Récupération terminée ==="
|
||||||
|
echo ""
|
||||||
|
echo "Prochaines étapes:"
|
||||||
|
echo " 1. Vérifiez que tout fonctionne: make health"
|
||||||
|
echo " 2. Consultez les logs si nécessaire: make logs"
|
||||||
|
|
||||||
|
# Lister les backups disponibles
|
||||||
|
BACKUP_DIR="${BACKUP_DESTINATION:-./backups}"
|
||||||
|
if [ -d "$BACKUP_DIR" ]; then
|
||||||
|
LATEST_BACKUP=$(find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
||||||
|
|
||||||
|
if [ -n "$LATEST_BACKUP" ]; then
|
||||||
|
echo " 3. Si problème persiste, restaurez le backup le plus récent:"
|
||||||
|
echo " make restore \"$LATEST_BACKUP\""
|
||||||
|
log "INFO" "Backup le plus récent: $LATEST_BACKUP"
|
||||||
|
else
|
||||||
|
echo " 3. Aucun backup disponible dans $BACKUP_DIR"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " 3. Dossier de backup introuvable: $BACKUP_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "SUCCESS" "Script de récupération terminé"
|
||||||
295
scripts/restore.sh
Normal file → Executable file
295
scripts/restore.sh
Normal file → Executable file
@@ -1,70 +1,277 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# scripts/restore.sh - Restauration d'un backup
|
# scripts/restore.sh - Restauration d'un backup
|
||||||
|
|
||||||
set -e
|
set -euo pipefail
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
# Variables globales
|
||||||
echo "Usage: $0 <backup_file.tar.gz>"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Charger .env en premier
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
echo "ERROR: Fichier .env introuvable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source .env
|
||||||
|
set +a
|
||||||
|
|
||||||
|
# Configuration des logs
|
||||||
|
LOG_DIR="./logs"
|
||||||
|
LOG_FILE="$PROJECT_ROOT/logs/restore_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
TEMP_DIR=""
|
||||||
|
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# Charger les fonctions communes (log avec couleurs)
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
# Vérifier les variables requises
|
||||||
|
if [ -z "${MYSQL_USER:-}" ] || [ -z "${MYSQL_PASSWORD:-}" ] || [ -z "${MYSQL_DATABASE:-}" ]; then
|
||||||
|
log "ERROR" "Variables MySQL non définies dans .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier les arguments
|
||||||
|
if [ -z "${1:-}" ]; then
|
||||||
|
log "ERROR" "Usage: $0 <backup_file.tar.gz>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
BACKUP_FILE="$1"
|
BACKUP_FILE="$1"
|
||||||
|
|
||||||
if [ ! -f "$BACKUP_FILE" ]; then
|
# Valider le chemin du fichier (éviter path traversal)
|
||||||
echo "❌ Fichier introuvable: $BACKUP_FILE"
|
if [[ "$BACKUP_FILE" =~ \.\. ]] || [[ "$BACKUP_FILE" == /* && ! "$BACKUP_FILE" =~ ^/home/ && ! "$BACKUP_FILE" =~ ^/tmp/ ]]; then
|
||||||
|
log "ERROR" "Chemin de fichier invalide ou non autorisé"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "⚠️ ATTENTION: Cette opération va écraser les données actuelles !"
|
# Résoudre le chemin absolu
|
||||||
read -p "Continuer? (yes/no): " confirm
|
BACKUP_FILE=$(realpath "$BACKUP_FILE" 2>/dev/null) || {
|
||||||
|
log "ERROR" "Impossible de résoudre le chemin: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ ! -f "$BACKUP_FILE" ]; then
|
||||||
|
log "ERROR" "Fichier introuvable: $BACKUP_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier que c'est bien un fichier tar.gz
|
||||||
|
if ! file "$BACKUP_FILE" | grep -q "gzip compressed"; then
|
||||||
|
log "ERROR" "Le fichier n'est pas une archive gzip valide"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier le checksum si disponible
|
||||||
|
CHECKSUM_FILE="${BACKUP_FILE}.sha256"
|
||||||
|
if [ -f "$CHECKSUM_FILE" ]; then
|
||||||
|
log "INFO" "Vérification du checksum..."
|
||||||
|
BACKUP_DIR=$(dirname "$BACKUP_FILE")
|
||||||
|
BACKUP_NAME=$(basename "$BACKUP_FILE")
|
||||||
|
|
||||||
|
if cd "$BACKUP_DIR" && sha256sum -c "$BACKUP_NAME.sha256" 2>>"$LOG_FILE"; then
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
log "INFO" "Checksum valide"
|
||||||
|
else
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
log "ERROR" "Checksum invalide! Le fichier pourrait être corrompu"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "WARN" "Pas de fichier checksum trouvé, impossible de vérifier l'intégrité"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "=== Restauration depuis: $BACKUP_FILE ==="
|
||||||
|
log "INFO" "Log file: $LOG_FILE"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log "WARN" "ATTENTION: Cette opération va écraser les données actuelles!"
|
||||||
|
read -r -p "Voulez-vous créer un backup de sécurité avant de continuer? (yes/no): " create_backup
|
||||||
|
|
||||||
|
if [ "$create_backup" = "yes" ]; then
|
||||||
|
log "INFO" "Création du backup de sécurité..."
|
||||||
|
if bash scripts/backup.sh 2>&1 | tee -a "$LOG_FILE"; then
|
||||||
|
log "INFO" "Backup de sécurité créé avec succès"
|
||||||
|
else
|
||||||
|
log "ERROR" "Échec du backup de sécurité"
|
||||||
|
read -r -p "Continuer quand même? (yes/no): " force_continue
|
||||||
|
if [ "$force_continue" != "yes" ]; then
|
||||||
|
log "INFO" "Restauration annulée"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -r -p "Continuer la restauration? (yes/no): " confirm
|
||||||
|
|
||||||
if [ "$confirm" != "yes" ]; then
|
if [ "$confirm" != "yes" ]; then
|
||||||
echo "Annulé."
|
log "INFO" "Restauration annulée"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Fonction de nettoyage
|
||||||
|
cleanup() {
|
||||||
|
local exit_code=$?
|
||||||
|
|
||||||
|
if [ -n "$TEMP_DIR" ] && [ -d "$TEMP_DIR" ]; then
|
||||||
|
log "INFO" "Nettoyage du répertoire temporaire..."
|
||||||
|
rm -rf "${TEMP_DIR:?}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
|
log "SUCCESS" "Restauration terminée avec succès"
|
||||||
|
else
|
||||||
|
log "ERROR" "Restauration échouée avec code: $exit_code"
|
||||||
|
log "ERROR" "Pour récupérer, utilisez: bash scripts/recover.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
# Extraire le backup
|
# Extraire le backup
|
||||||
TEMP_DIR=$(mktemp -d)
|
TEMP_DIR=$(mktemp -d)
|
||||||
echo "📂 Extraction vers $TEMP_DIR..."
|
log "INFO" "Extraction vers $TEMP_DIR..."
|
||||||
tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR"
|
|
||||||
|
|
||||||
BACKUP_DIR=$(ls -1 "$TEMP_DIR" | head -n1)
|
if ! tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR" 2>>"$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors de l'extraction"
|
||||||
# Arrêter les services
|
exit 1
|
||||||
echo "⏹️ Arrêt des services..."
|
|
||||||
docker-compose down
|
|
||||||
|
|
||||||
# Restaurer la base de données
|
|
||||||
echo "💾 Restauration de la base de données..."
|
|
||||||
docker-compose up -d db
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
docker-compose exec -T db mysql \
|
|
||||||
-u"$MYSQL_USER" \
|
|
||||||
-p"$MYSQL_PASSWORD" \
|
|
||||||
"$MYSQL_DATABASE" \
|
|
||||||
< "$TEMP_DIR/$BACKUP_DIR/database.sql"
|
|
||||||
|
|
||||||
# Restaurer les fichiers
|
|
||||||
echo "📁 Restauration des fichiers..."
|
|
||||||
tar -xzf "$TEMP_DIR/$BACKUP_DIR/config.tar.gz" -C ./data/config
|
|
||||||
tar -xzf "$TEMP_DIR/$BACKUP_DIR/data.tar.gz" -C ./data/data
|
|
||||||
|
|
||||||
if [ -f "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" ]; then
|
|
||||||
tar -xzf "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" -C ./data/custom_apps
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Redémarrer
|
# Trouver le répertoire de backup
|
||||||
echo "▶️ Redémarrage des services..."
|
BACKUP_DIR=$(find "$TEMP_DIR" -mindepth 1 -maxdepth 1 -type d | head -n1)
|
||||||
docker-compose up -d
|
if [ -z "$BACKUP_DIR" ]; then
|
||||||
|
log "ERROR" "Aucun répertoire trouvé dans l'archive"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "Backup extrait: $(basename "$BACKUP_DIR")"
|
||||||
|
|
||||||
|
# Vérifier que les fichiers requis existent
|
||||||
|
if [ ! -f "$BACKUP_DIR/database.sql" ]; then
|
||||||
|
log "ERROR" "Fichier database.sql manquant dans l'archive"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$BACKUP_DIR/config.tar.gz" ]; then
|
||||||
|
log "ERROR" "Fichier config.tar.gz manquant dans l'archive"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Arrêter les services
|
||||||
|
log "INFO" "Arrêt des services..."
|
||||||
|
docker-compose down 2>>"$LOG_FILE"
|
||||||
|
|
||||||
|
# Démarrer uniquement la base de données
|
||||||
|
log "INFO" "Démarrage de la base de données..."
|
||||||
|
docker-compose up -d db 2>>"$LOG_FILE"
|
||||||
|
|
||||||
|
# Attendre que la base de données soit prête
|
||||||
|
log "INFO" "Attente de la base de données..."
|
||||||
|
for i in {1..30}; do
|
||||||
|
if docker-compose exec -T db mysqladmin ping -h localhost --silent 2>>"$LOG_FILE"; then
|
||||||
|
log "INFO" "Base de données prête"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ "$i" -eq 30 ]; then
|
||||||
|
log "ERROR" "Timeout: La base de données n'est pas prête"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Backup de sécurité de la DB actuelle
|
||||||
|
log "INFO" "Backup de sécurité de la base de données actuelle..."
|
||||||
|
SAFETY_BACKUP="$TEMP_DIR/safety_db_backup.sql"
|
||||||
|
if docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysqldump \
|
||||||
|
-u\"\$MYSQL_USER\" \
|
||||||
|
\"\$MYSQL_DATABASE\" \
|
||||||
|
--single-transaction \
|
||||||
|
--quick" > "$SAFETY_BACKUP" 2>>"$LOG_FILE"; then
|
||||||
|
log "INFO" "Backup de sécurité créé: $SAFETY_BACKUP"
|
||||||
|
else
|
||||||
|
log "WARN" "Impossible de créer un backup de sécurité de la DB"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restaurer la base de données
|
||||||
|
log "INFO" "Restauration de la base de données..."
|
||||||
|
if ! docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysql \
|
||||||
|
-u\"\$MYSQL_USER\" \
|
||||||
|
\"\$MYSQL_DATABASE\"" < "$BACKUP_DIR/database.sql" 2>>"$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors de la restauration de la base de données"
|
||||||
|
log "ERROR" "Backup de sécurité disponible: $SAFETY_BACKUP"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log "INFO" "Base de données restaurée"
|
||||||
|
|
||||||
|
# Démarrer tous les services
|
||||||
|
log "INFO" "Démarrage de tous les services..."
|
||||||
|
docker-compose up -d 2>>"$LOG_FILE"
|
||||||
|
|
||||||
|
# Attendre que Nextcloud soit prêt
|
||||||
|
log "INFO" "Attente du démarrage de Nextcloud..."
|
||||||
|
for i in {1..60}; do
|
||||||
|
if docker-compose exec -T nextcloud curl -f http://localhost/status.php >/dev/null 2>&1; then
|
||||||
|
log "INFO" "Nextcloud prêt"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ "$i" -eq 60 ]; then
|
||||||
|
log "ERROR" "Timeout: Nextcloud n'est pas prêt"
|
||||||
|
log "ERROR" "Vérifiez les logs: docker-compose logs nextcloud"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Restaurer la configuration
|
||||||
|
log "INFO" "Restauration de la configuration..."
|
||||||
|
if ! docker-compose exec -T -u www-data nextcloud tar -xzf - -C /var/www/html/config < "$BACKUP_DIR/config.tar.gz" 2>>"$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors de la restauration de la configuration"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log "INFO" "Configuration restaurée"
|
||||||
|
|
||||||
|
# Restaurer les données
|
||||||
|
if [ -f "$BACKUP_DIR/data.tar.gz" ]; then
|
||||||
|
log "INFO" "Restauration des données utilisateurs..."
|
||||||
|
if ! docker-compose exec -T -u www-data nextcloud tar -xzf - -C /var/www/html/data < "$BACKUP_DIR/data.tar.gz" 2>>"$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors de la restauration des données"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log "INFO" "Données restaurées"
|
||||||
|
else
|
||||||
|
log "WARN" "Pas de fichier data.tar.gz trouvé"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restaurer les apps personnalisées
|
||||||
|
if [ -f "$BACKUP_DIR/apps.tar.gz" ]; then
|
||||||
|
log "INFO" "Restauration des apps personnalisées..."
|
||||||
|
if docker-compose exec -T -u www-data nextcloud tar -xzf - -C /var/www/html/custom_apps < "$BACKUP_DIR/apps.tar.gz" 2>>"$LOG_FILE"; then
|
||||||
|
log "INFO" "Apps restaurées"
|
||||||
|
else
|
||||||
|
log "WARN" "Erreur lors de la restauration des apps"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "INFO" "Pas d'apps personnalisées à restaurer"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Désactiver le mode maintenance
|
||||||
|
log "INFO" "Désactivation du mode maintenance..."
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE" || log "WARN" "Impossible de désactiver le mode maintenance"
|
||||||
|
|
||||||
# Réparer et scanner
|
# Réparer et scanner
|
||||||
echo "🔧 Réparation..."
|
log "INFO" "Réparation de l'installation..."
|
||||||
sleep 30
|
docker-compose exec -T -u www-data nextcloud php occ maintenance:repair 2>>"$LOG_FILE" || log "WARN" "Erreur lors de la réparation"
|
||||||
docker-compose exec -u www-data nextcloud php occ maintenance:repair
|
|
||||||
docker-compose exec -u www-data nextcloud php occ files:scan --all
|
|
||||||
|
|
||||||
# Nettoyer
|
log "INFO" "Scan des fichiers..."
|
||||||
rm -rf "$TEMP_DIR"
|
docker-compose exec -T -u www-data nextcloud php occ files:scan --all 2>>"$LOG_FILE" || log "WARN" "Erreur lors du scan"
|
||||||
|
|
||||||
echo "✅ Restauration terminée !"
|
log "INFO" "=== Restauration terminée ==="
|
||||||
|
log "INFO" "Vérifiez que tout fonctionne: make health"
|
||||||
|
|||||||
176
scripts/update.sh
Normal file → Executable file
176
scripts/update.sh
Normal file → Executable file
@@ -1,47 +1,167 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# scripts/update.sh - Mise à jour Nextcloud
|
# scripts/update.sh - Mise à jour Nextcloud
|
||||||
|
|
||||||
set -e
|
set -euo pipefail
|
||||||
|
|
||||||
echo "🔄 Mise à jour de Nextcloud"
|
# Variables globales
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Configuration des logs
|
||||||
|
LOG_DIR="./logs"
|
||||||
|
LOG_FILE="$PROJECT_ROOT/logs/update_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
MAINTENANCE_ENABLED=false
|
||||||
|
COMPOSE_BACKUP=""
|
||||||
|
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# Charger les fonctions communes (log avec couleurs)
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
# Fonction de nettoyage en cas d'erreur
|
||||||
|
cleanup() {
|
||||||
|
local exit_code=$?
|
||||||
|
|
||||||
|
if [ "$exit_code" -ne 0 ]; then
|
||||||
|
log "ERROR" "Erreur détectée lors de la mise à jour (code: $exit_code)"
|
||||||
|
log "WARN" "IMPORTANT: Vérifiez les logs et considérez une restauration si nécessaire"
|
||||||
|
|
||||||
|
# Restaurer le docker-compose.yml si backup existe
|
||||||
|
if [ -n "$COMPOSE_BACKUP" ] && [ -f "$COMPOSE_BACKUP" ]; then
|
||||||
|
log "INFO" "Restauration du docker-compose.yml..."
|
||||||
|
cp "$COMPOSE_BACKUP" docker-compose.yml || log "ERROR" "Impossible de restaurer docker-compose.yml"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Désactiver le mode maintenance si activé
|
||||||
|
if [ "$MAINTENANCE_ENABLED" = true ]; then
|
||||||
|
log "INFO" "Tentative de désactivation du mode maintenance..."
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nettoyer le backup temporaire
|
||||||
|
if [ -n "$COMPOSE_BACKUP" ] && [ -f "$COMPOSE_BACKUP" ]; then
|
||||||
|
rm -f "$COMPOSE_BACKUP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
|
log "SUCCESS" "Mise à jour terminée avec succès"
|
||||||
|
else
|
||||||
|
log "ERROR" "Mise à jour échouée avec code: $exit_code"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
log "INFO" "=== Mise à jour de Nextcloud ==="
|
||||||
|
log "INFO" "Log file: $LOG_FILE"
|
||||||
|
|
||||||
|
# Afficher la version actuelle
|
||||||
|
log "INFO" "Version actuelle:"
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ status 2>&1 | tee -a "$LOG_FILE" || log "WARN" "Impossible d'obtenir le statut actuel"
|
||||||
|
|
||||||
# Backup avant update
|
# Backup avant update
|
||||||
echo "💾 Backup de sécurité..."
|
log "INFO" "Création du backup de sécurité..."
|
||||||
bash scripts/backup.sh
|
if ! bash scripts/backup.sh 2>&1 | tee -a "$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors du backup, abandon de la mise à jour"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Mode maintenance
|
# Sauvegarder le docker-compose.yml
|
||||||
echo "⏸️ Mode maintenance activé"
|
log "INFO" "Sauvegarde de docker-compose.yml..."
|
||||||
docker-compose exec -u www-data nextcloud php occ maintenance:mode --on
|
COMPOSE_BACKUP="/tmp/docker-compose.yml.backup.$$"
|
||||||
|
cp docker-compose.yml "$COMPOSE_BACKUP" || {
|
||||||
|
log "ERROR" "Impossible de sauvegarder docker-compose.yml"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
log "INFO" "docker-compose.yml sauvegardé: $COMPOSE_BACKUP"
|
||||||
|
|
||||||
# Pull nouvelle image
|
# Pull nouvelle image de base et rebuild image custom
|
||||||
echo "📥 Téléchargement de la nouvelle version..."
|
log "INFO" "Téléchargement de la nouvelle version de base..."
|
||||||
docker-compose pull nextcloud
|
if ! docker pull nextcloud:latest 2>&1 | tee -a "$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors du téléchargement de l'image de base"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "Rebuild de l'image personnalisée (avec ffmpeg)..."
|
||||||
|
if ! docker-compose build --no-cache nextcloud 2>&1 | tee -a "$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors du rebuild de l'image personnalisée"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Mode maintenance avant le restart
|
||||||
|
log "INFO" "Activation du mode maintenance..."
|
||||||
|
if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --on 2>>"$LOG_FILE"; then
|
||||||
|
MAINTENANCE_ENABLED=true
|
||||||
|
log "INFO" "Mode maintenance activé"
|
||||||
|
else
|
||||||
|
log "ERROR" "Impossible d'activer le mode maintenance"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Restart
|
# Restart
|
||||||
echo "🔄 Redémarrage..."
|
log "INFO" "Redémarrage des services..."
|
||||||
docker-compose up -d --force-recreate nextcloud cron
|
if ! docker-compose up -d --force-recreate nextcloud cron 2>&1 | tee -a "$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors du redémarrage"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Attendre que Nextcloud soit prêt
|
# Attendre que Nextcloud soit prêt
|
||||||
echo "⏳ Attente du démarrage..."
|
log "INFO" "Attente du démarrage de Nextcloud (max 2 minutes)..."
|
||||||
sleep 30
|
for i in {1..120}; do
|
||||||
|
if docker-compose exec -T nextcloud curl -f http://localhost/status.php >/dev/null 2>&1; then
|
||||||
|
log "INFO" "Nextcloud prêt (${i}s)"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ "$i" -eq 120 ]; then
|
||||||
|
log "ERROR" "Timeout: Nextcloud n'est pas prêt après 2 minutes"
|
||||||
|
log "ERROR" "Vérifiez les logs: docker-compose logs nextcloud"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Désactiver temporairement le mode maintenance pour permettre l'upgrade
|
||||||
|
log "INFO" "Préparation de l'upgrade..."
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE" || true
|
||||||
|
MAINTENANCE_ENABLED=false
|
||||||
|
|
||||||
# Upgrade via OCC
|
# Upgrade via OCC
|
||||||
echo "⬆️ Lancement de l'upgrade..."
|
log "INFO" "Lancement de l'upgrade..."
|
||||||
docker-compose exec -u www-data nextcloud php occ upgrade
|
if ! docker-compose exec -T -u www-data nextcloud php occ upgrade 2>&1 | tee -a "$LOG_FILE"; then
|
||||||
|
log "ERROR" "Erreur lors de l'upgrade"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Scan et indices
|
# Afficher la nouvelle version
|
||||||
echo "🔍 Scan des fichiers..."
|
log "INFO" "Nouvelle version:"
|
||||||
docker-compose exec -u www-data nextcloud php occ files:scan --all
|
docker-compose exec -T -u www-data nextcloud php occ status 2>&1 | tee -a "$LOG_FILE" || log "WARN" "Impossible d'obtenir le nouveau statut"
|
||||||
|
|
||||||
echo "📊 Ajout des indices manquants..."
|
# Opérations de maintenance post-upgrade (non bloquantes)
|
||||||
docker-compose exec -u www-data nextcloud php occ db:add-missing-indices
|
log "INFO" "Scan des fichiers..."
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ files:scan --all 2>&1 | tee -a "$LOG_FILE" || log "WARN" "Erreur lors du scan"
|
||||||
|
|
||||||
echo "🔧 Conversion des colonnes..."
|
log "INFO" "Ajout des indices manquants..."
|
||||||
docker-compose exec -u www-data nextcloud php occ db:convert-filecache-bigint --no-interaction
|
docker-compose exec -T -u www-data nextcloud php occ db:add-missing-indices 2>&1 | tee -a "$LOG_FILE" || log "WARN" "Erreur lors de l'ajout des indices"
|
||||||
|
|
||||||
# Désactiver maintenance
|
log "INFO" "Conversion des colonnes BigInt..."
|
||||||
echo "▶️ Désactivation du mode maintenance"
|
docker-compose exec -T -u www-data nextcloud php occ db:convert-filecache-bigint --no-interaction 2>&1 | tee -a "$LOG_FILE" || log "WARN" "Erreur lors de la conversion"
|
||||||
docker-compose exec -u www-data nextcloud php occ maintenance:mode --off
|
|
||||||
|
|
||||||
echo "✅ Mise à jour terminée !"
|
# Désactiver le mode maintenance
|
||||||
docker-compose exec -u www-data nextcloud php occ status
|
log "INFO" "Désactivation du mode maintenance..."
|
||||||
|
if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE"; then
|
||||||
|
MAINTENANCE_ENABLED=false
|
||||||
|
log "INFO" "Mode maintenance désactivé"
|
||||||
|
else
|
||||||
|
log "WARN" "Impossible de désactiver le mode maintenance"
|
||||||
|
log "WARN" "Exécutez manuellement: make occ maintenance:mode --off"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Statut final
|
||||||
|
log "INFO" "=== Mise à jour terminée ==="
|
||||||
|
log "INFO" "Vérifiez que tout fonctionne: make health"
|
||||||
|
docker-compose exec -T -u www-data nextcloud php occ status 2>&1 | tee -a "$LOG_FILE" || true
|
||||||
|
|||||||
Reference in New Issue
Block a user