# Bocage Drive Drive privé (React 19 + Vite 8 + Tailwind v4 + composants shadcn/ui, Django REST Framework, MariaDB et Docker). Construit à partir de la structure du site de la boulangerie, **sans ses modules de planning / pointage**. ## Fonctions incluses - Connexion avec les comptes Django, inscription publique désactivée. - Dossiers imbriqués, import par bouton et glisser-déposer, classement en liste/grille, recherche, tri. - Aperçu des images, PDF et fichiers audio ; téléchargement direct avec des URL signées valables 5 minutes. - Renommer, déplacer, marquer favori, partager, mettre à la corbeille, restaurer et supprimer définitivement. - Espace « Partagés avec moi » : partage **en lecture à tous les comptes connectés**, uniquement pour les fichiers et dossiers à la racine (le partage d'un dossier inclut sa descendance). - Import reprenable par blocs de 8 Mio dès 8 Mio ; la progression est conservée dans le navigateur de l'utilisateur. Taille maximale réglable (50 Gio par défaut dans `.env.example`). - Fichiers sur un **dossier disque persistant**, métadonnées dans MariaDB. - Thème clair/sombre, interface responsive avec composants shadcn/ui repris de la structure existante. ## Méthode 1 — Docker Compose (MariaDB intégrée) Depuis le dossier `BocageDrive` : ```bash cp .env.example .env # Modifier les secrets, ALLOWED_HOSTS (IP / nom de domaine), etc. # Exemple pour un secret (ne pas copier un secret trouvé en ligne) : python3 -c "import secrets; print(secrets.token_urlsafe(64))" docker compose up -d --build docker compose exec backend python manage.py createsuperuser ``` Puis ouvrir `http://IP_DU_SERVEUR:1028/`. Les comptes supplémentaires se créent dans `http://IP_DU_SERVEUR:1028/django-admin/` > Utilisateurs. Les utilisateurs ordinaires ne peuvent pas gérer les autres comptes. Le frontend est servi par nginx sur **1028**. Django écoute sur **1029 uniquement sur le réseau Compose**. Le frontend proxifie `/api/`, `/static/` et `/django-admin/` ; pas besoin d'exposer Django séparément. MariaDB reste privée au réseau Docker (pas de port 3306 exposé sur l'hôte). ### Persistance / sauvegarde - Fichiers : `./storage/files/`. - Importations en cours : `./storage/tmp/`. - Base MariaDB : volume `db_data` de Compose. Sauvegarder **ensemble** le volume MariaDB et le dossier `storage`. Ne pas exécuter `docker compose down -v` : cela supprimerait la base stockée dans le volume. ## Méthode 2 — Un conteneur Pterodactyl (base MariaDB externe) Les fichiers `Dockerfile.pterodactyl` et `dockerfile` (identiques) préparent un conteneur autonome : **frontend nginx :1028 + Django Gunicorn :1029 en interne**. Il ne lance pas MariaDB : utiliser une base MariaDB déjà disponible depuis Pterodactyl. Cette variante évite d'avoir besoin de Docker-in-Docker ou de Docker Compose **dans** le conteneur Pterodactyl. Construire l'image sur une machine disposant de Docker : ```bash docker build -f Dockerfile.pterodactyl -t bocage-drive:latest . ``` Publier l'image sur le registre utilisé par ton nœud puis associer cette image à un egg approprié, avec commande de démarrage par défaut `/opt/drive/start.sh`, allocation TCP **1028**. Le conteneur doit avoir un dossier **`/home/container/storage` persistant** et accessible en écriture par l'utilisateur UID 999. Selon la configuration du nœud, tu devras ajuster le UID de l'image ou les permissions du volume. Variables d'environnement à ajouter à l'egg / serveur Pterodactyl : ```env MYSQL_HOST=IP_OU_HOTE_DE_TA_MARIADB MYSQL_PORT=3306 MYSQL_DATABASE=bocagedrive MYSQL_USER=un_utilisateur_sql_dedie MYSQL_PASSWORD=UN_SECRET DJANGO_SECRET_KEY=UN_AUTRE_SECRET_LONG DEBUG=false ALLOWED_HOSTS=ton-domaine.fr,192.168.1.19,localhost,127.0.0.1 DRIVE_STORAGE_ROOT=/home/container/storage/files DRIVE_MAX_FILE_SIZE_MB=51200 ``` **Ne mets pas `MYSQL_HOST=db` dans ce mode**, sauf si un service DNS réellement accessible s'appelle `db`. `db` est le nom du service Docker Compose de la méthode 1. Crée la base et un utilisateur ayant les droits sur cette base avant de démarrer l'image. Le conteneur Pterodactyl ne crée pas la base externe. Créer le premier utilisateur administrateur **dans le conteneur**, une fois le démarrage réussi : ```bash cd /opt/drive/backend python manage.py createsuperuser ``` Cette procédure nécessite la capacité de configurer une **image Docker personnalisée** sur ton Pterodactyl. Sur les panels qui n'autorisent pas cela, passer par la méthode Compose **sur l'hôte** ou adapter un egg de déploiement Python/Node existant. Le Dockerfile est fourni, mais je ne peux pas créer l'egg ou modifier les allocations de ton panel depuis cette archive. ## Reverse proxy et gros fichiers - Utilise **HTTPS** sur l'accès distant : des identifiants circulent à chaque connexion. - Configure ton reverse proxy externe avec une limite suffisante : `client_max_body_size 0;` côté nginx et `proxy_request_buffering off;` pour ne pas recopie entière des très gros imports (le nginx fourni est déjà configuré). - Les envois de 8 Mio ou plus sont fractionnés en blocs de 8 Mio et peuvent reprendre après recharge/incident côté navigateur. Un navigateur différent ne récupère pas automatiquement la session locale de reprise. - Limite par fichier : `DRIVE_MAX_FILE_SIZE_MB`. L'espace disque est celui alloué au serveur Pterodactyl, **pas** un quota par utilisateur. - Une importation interrompue reste dans `storage/tmp` jusqu'à reprise. Pour nettoyer les sessions de plus de 14 jours : `python manage.py cleanup_uploads --days 14` dans le backend (ou `docker compose exec backend python manage.py cleanup_uploads --days 14`). Ne pas vider `tmp` pendant un import actif. ## Authentification / sécurité - Pas d'inscription ouverte ; les comptes sont créés via Django Admin. - Le JWT est conservé dans `sessionStorage` du navigateur, le renouvellement dans la session du même onglet (refresh 7 jours, access 30 minutes). Après fermeture de l'onglet, reconnexion nécessaire. - Les contrôles d'accès s'effectuent côté Django ; l'UI ne suffit pas pour protéger un document. - Les URL de téléchargement sont temporaires (5 min) et leur possession suffit à accéder au fichier pendant leur validité. Ne les partage pas publiquement. - Les utilisateurs peuvent modifier leurs propres fichiers et dossiers, et lire les racines partagées par d'autres comptes. Les administrateurs Django ont accès aux objets via les vues et peuvent gérer les comptes. ## Limites de cette première version Ce n'est **pas encore** un Nextcloud complet : pas de lien public permanent, pas de partage à un utilisateur précis, pas d'historique des versions, pas d'édition collaborative, pas de quota individuel, pas de WebDAV/Samba et pas de stockage chiffré de bout en bout. L'aperçu vidéo et la synchronisation automatique type client Drive ne sont pas inclus. Cette version prend en charge le téléchargement et l'import via navigateur. Pour les gros volumes de rushs (plusieurs dizaines de Go), le fractionnement évite de tout recommencer, mais les performances et la reprise sont à valider sur le réseau réel. Sauvegarde et HTTPS sont indispensables avant un usage important. ## Vérifications manuelles conseillées 1. Créer deux comptes : propriétaire A et salarié B. 2. Avec A, créer un dossier, importer un fichier, le renommer, le télécharger et l'ouvrir. 3. Avec B, vérifier que le dossier privé de A n'est pas accessible, puis que le dossier partagé de A est accessible en lecture seule. 4. Déplacer un dossier, mettre un fichier en corbeille, restaurer, puis supprimer définitivement un document test. 5. Couper volontairement la connexion au milieu d'un gros import et relancer le même fichier depuis le même navigateur pour vérifier la reprise. 6. Redémarrer le conteneur et vérifier que les fichiers et comptes sont toujours là. ## Tests automatisés Les tests Django sont dans `backend/drive/tests.py` : ```bash docker compose exec -e USE_SQLITE=1 backend python manage.py test drive ``` Note : dans Compose, utiliser la base de test dédiée automatique Django (normalement la MariaDB de tests) convient aussi : `docker compose exec backend python manage.py test drive` ; la variante SQLite évite d'avoir à créer une base MySQL de tests et n'est pas nécessaire en production.