Compare commits
22 Commits
a7c14f9000
...
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 |
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
|
||||
@@ -20,6 +20,11 @@ REDIS_HOST_PASSWORD=CHANGEME_GENERATE_STRONG_PASSWORD
|
||||
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)
|
||||
# ============================================
|
||||
|
||||
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/*
|
||||
30
Makefile
30
Makefile
@@ -1,4 +1,4 @@
|
||||
.PHONY: help up down restart logs logs-all ps shell db-shell redis-shell occ backup restore update health check-health recover clean permissions
|
||||
.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
|
||||
@@ -47,6 +47,10 @@ help:
|
||||
@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"
|
||||
@@ -124,6 +128,30 @@ clean:
|
||||
@$(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
|
||||
%:
|
||||
@:
|
||||
|
||||
236
README.md
236
README.md
@@ -16,12 +16,13 @@ Déploiement Nextcloud avec Docker Compose comprenant MariaDB 10.11, Redis (cach
|
||||
|
||||
## Architecture
|
||||
|
||||
Le déploiement comprend 4 services:
|
||||
Le déploiement comprend 5 services:
|
||||
|
||||
- **nextcloud**: Application Nextcloud (port 127.0.0.1:8888:80)
|
||||
- **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**:
|
||||
|
||||
@@ -113,11 +114,126 @@ Les paramètres PHP sont préconfigurés dans docker-compose.yml:
|
||||
|
||||
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
|
||||
|
||||
@@ -223,7 +339,7 @@ make update
|
||||
1. 💾 **Backup automatique de sécurité**
|
||||
- Exécute `scripts/backup.sh` complet
|
||||
- Archive créée dans `./backups/`
|
||||
2. 📥 Télécharge la nouvelle image Docker Nextcloud
|
||||
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)
|
||||
@@ -339,6 +455,119 @@ 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
|
||||
|
||||
### Vérifications de santé
|
||||
@@ -381,6 +610,7 @@ docker compose exec redis redis-cli -a ${REDIS_HOST_PASSWORD} INFO stats
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
max_connections = 200
|
||||
|
||||
# Gros fichiers - augmenter la taille max des paquets
|
||||
max_allowed_packet = 1G
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
services:
|
||||
nextcloud:
|
||||
image: nextcloud:latest
|
||||
build: .
|
||||
image: nextcloud-custom:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:8888:80"
|
||||
volumes:
|
||||
- ./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:
|
||||
# Database
|
||||
- MYSQL_HOST=db
|
||||
@@ -23,12 +33,16 @@ services:
|
||||
- REDIS_HOST_PASSWORD=${REDIS_HOST_PASSWORD}
|
||||
# PHP
|
||||
- PHP_MEMORY_LIMIT=4096M
|
||||
- PHP_UPLOAD_MAX_FILESIZE=2G
|
||||
- PHP_POST_MAX_SIZE=2G
|
||||
- PHP_MAX_EXECUTION_TIME=1800
|
||||
- PHP_MAX_INPUT_TIME=1800
|
||||
- PHP_UPLOAD_MAX_FILESIZE=10G
|
||||
- PHP_POST_MAX_SIZE=10G
|
||||
- PHP_MAX_EXECUTION_TIME=7200
|
||||
- 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_BODY_LIMIT=2147483648
|
||||
- APACHE_BODY_LIMIT=0
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost/status.php"]
|
||||
interval: 30s
|
||||
@@ -42,16 +56,32 @@ services:
|
||||
networks:
|
||||
- nextcloud-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:
|
||||
image: redis:alpine
|
||||
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:
|
||||
- nextcloud-net
|
||||
|
||||
cron:
|
||||
image: nextcloud:latest
|
||||
image: nextcloud-custom:latest
|
||||
restart: always
|
||||
volumes_from:
|
||||
- nextcloud
|
||||
@@ -63,6 +93,28 @@ services:
|
||||
networks:
|
||||
- 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:
|
||||
image: mariadb:10.11
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -114,7 +114,8 @@ if [ -z "$REQUIRED_SPACE" ] || [ "$REQUIRED_SPACE" = "0" ]; then
|
||||
fi
|
||||
|
||||
# Obtenir l'espace disponible (enlever les espaces/newlines)
|
||||
AVAILABLE_SPACE=$(df -B1 "$BACKUP_DIR" | awk 'NR==2 {print $4}' | tr -d '[:space:]')
|
||||
# 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
|
||||
|
||||
@@ -8,6 +8,14 @@ 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"
|
||||
@@ -131,18 +139,11 @@ 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"
|
||||
|
||||
# Charger .env pour tester la connexion
|
||||
if [ -f .env ]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source .env
|
||||
set +a
|
||||
|
||||
if docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysql -u\"\$MYSQL_USER\" -e 'SELECT 1' >/dev/null 2>&1"; then
|
||||
check_ok "Connexion MySQL fonctionnelle"
|
||||
else
|
||||
check_fail "Impossible de se connecter à MySQL"
|
||||
fi
|
||||
# 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"
|
||||
@@ -181,14 +182,20 @@ else
|
||||
check_fail "Utilisation disque: ${DISK_USAGE}% (${DISK_AVAIL} disponible) - CRITIQUE"
|
||||
fi
|
||||
|
||||
# Vérifier la taille des données
|
||||
if [ -d ./data ]; then
|
||||
DATA_SIZE=$(du -sh ./data 2>/dev/null | cut -f1 || echo "N/A")
|
||||
check_ok "Taille des données: $DATA_SIZE"
|
||||
# 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 "N/A")
|
||||
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
|
||||
|
||||
@@ -240,7 +247,10 @@ 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 "N/A")
|
||||
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"
|
||||
|
||||
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é"
|
||||
@@ -80,10 +80,16 @@ cp docker-compose.yml "$COMPOSE_BACKUP" || {
|
||||
}
|
||||
log "INFO" "docker-compose.yml sauvegardé: $COMPOSE_BACKUP"
|
||||
|
||||
# Pull nouvelle image
|
||||
log "INFO" "Téléchargement de la nouvelle version..."
|
||||
if ! docker-compose pull nextcloud 2>&1 | tee -a "$LOG_FILE"; then
|
||||
log "ERROR" "Erreur lors du téléchargement de l'image"
|
||||
# Pull nouvelle image de base et rebuild image custom
|
||||
log "INFO" "Téléchargement de la nouvelle version de base..."
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user