This commit is contained in:
Louis Mazin 2026-10-13 20:11:33 +02:00
parent 4dfe644681
commit 94953b3fef
5 changed files with 62 additions and 80 deletions

View File

@ -1,6 +1,6 @@
# Bocage Drive # GoodDrive
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**. Drive privé (React 19 + Vite 8 + Tailwind v4 + composants shadcn/ui, Django REST Framework, MySQL 8 et Docker). Construit à partir de la structure du site de la boulangerie, **sans ses modules de planning / pointage**.
## Fonctions incluses ## Fonctions incluses
@ -10,12 +10,12 @@ Drive privé (React 19 + Vite 8 + Tailwind v4 + composants shadcn/ui, Django RES
- Renommer, déplacer, marquer favori, partager, mettre à la corbeille, restaurer et supprimer définitivement. - 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). - 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`). - 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. - Fichiers sur un **dossier disque persistant**, métadonnées dans MySQL 8.
- Thème clair/sombre, interface responsive avec composants shadcn/ui repris de la structure existante. - Thème clair/sombre, interface responsive avec composants shadcn/ui repris de la structure existante.
## Méthode 1 — Docker Compose (MariaDB intégrée) ## Méthode 1 — Docker Compose (MySQL 8 intégré)
Depuis le dossier `BocageDrive` : Depuis le dossier `GoodDrive` :
```bash ```bash
cp .env.example .env cp .env.example .env
@ -28,53 +28,21 @@ 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. 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). Le frontend React/Vite (mode développement de l’archive) écoute sur **1028** ; Django écoute sur **1029**, uniquement sur le réseau Compose. Le proxy de développement Vite transfère `/api/` et `/django-admin/` vers Django. MySQL 8 reste privé au réseau Docker (aucun port 3306 publié). Pour une mise en production publique, remplacer le serveur de développement Vite/Django par un serveur web et Gunicorn correctement configurés.
### Persistance / sauvegarde ### Persistance / sauvegarde
- Fichiers : `./storage/files/`. - Fichiers : `./storage/files/`.
- Importations en cours : `./storage/tmp/`. - Importations en cours : `./storage/tmp/`.
- Base MariaDB : volume `db_data` de Compose. - Base MySQL 8 : **nouveau volume `mysql8_data`** de Compose. L’ancien `db_data` n’est pas supprimé ni réutilisé. Voir `MYSQL8_MIGRATION.md`.
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. Sauvegarder **ensemble** le volume MySQL 8 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) ## Méthode 2 — Pterodactyl (MySQL 8 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. Si GoodDrive tourne dans un seul conteneur Pterodactyl, son backend doit accéder à une **base MySQL 8 externe**, via les variables `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_DATABASE`, `MYSQL_USER` et `MYSQL_PASSWORD` de Pterodactyl. `MYSQL_HOST=db` n'est valable que pour le Docker Compose ci-dessus.
Construire l'image sur une machine disposant de Docker : **Limite de l'archive fournie :** le `dockerfile` racine référence un `start.sh` absent et ne constitue pas, tel quel, une image monocon­teneur prête à déployer. Le présent correctif porte sur le mode Docker Compose. Une image Pterodactyl autonome nécessite son propre script de lancement et un serveur HTTP de production.
```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 ## Reverse proxy et gros fichiers
@ -115,4 +83,8 @@ Les tests Django sont dans `backend/drive/tests.py` :
docker compose exec -e USE_SQLITE=1 backend python manage.py test drive 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. Note : dans Compose, utiliser la base de test dédiée automatique Django (normalement la base MySQL 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 à réserver aux tests.
## Passage depuis MariaDB / erreur `ibdata1`
Consulte **`MYSQL8_MIGRATION.md`**. Ne recycle pas un datadir MariaDB dans MySQL 8 : ce correctif crée un volume distinct sans effacer l’ancien.

View File

@ -29,7 +29,7 @@ if os.environ.get('USE_SQLITE')=='1':
DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3','NAME':BASE_DIR/'test.sqlite3'}} DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3','NAME':BASE_DIR/'test.sqlite3'}}
else: else:
DATABASES={'default':{'ENGINE':'django.db.backends.mysql', DATABASES={'default':{'ENGINE':'django.db.backends.mysql',
'NAME':os.environ.get('MYSQL_DATABASE','bocagedrive'),'USER':os.environ.get('MYSQL_USER','bocagedrive'), 'NAME':os.environ.get('MYSQL_DATABASE','gooddrive'),'USER':os.environ.get('MYSQL_USER','gooddrive'),
'PASSWORD':os.environ.get('MYSQL_PASSWORD',''),'HOST':os.environ.get('MYSQL_HOST','db'), 'PASSWORD':os.environ.get('MYSQL_PASSWORD',''),'HOST':os.environ.get('MYSQL_HOST','db'),
'PORT':os.environ.get('MYSQL_PORT','3306'), 'OPTIONS':{'charset':'utf8mb4'}}} 'PORT':os.environ.get('MYSQL_PORT','3306'), 'OPTIONS':{'charset':'utf8mb4'}}}
AUTH_PASSWORD_VALIDATORS=[ AUTH_PASSWORD_VALIDATORS=[

View File

@ -0,0 +1,23 @@
# Generated by Django 5.2.18 on 2026-10-13 17:54
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('drive', '0002_uploadsession'),
]
operations = [
migrations.RenameIndex(
model_name='driveitem',
new_name='drive_drive_owner_i_b49586_idx',
old_name='drive_owner_parent_idx',
),
migrations.RenameIndex(
model_name='driveitem',
new_name='drive_drive_owner_i_a6138a_idx',
old_name='drive_owner_trash_idx',
),
]

View File

@ -1,32 +0,0 @@
server {
listen 1028;
server_name _;
root /usr/share/nginx/html;
index index.html;
client_max_body_size 0;
client_body_timeout 3600s;
send_timeout 3600s;
location /api/ {
proxy_pass http://backend:1029;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_request_buffering off;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
location /django-admin/ {
proxy_pass http://backend:1029;
proxy_set_header Host $host;
}
location /static/ {
proxy_pass http://backend:1029;
proxy_set_header Host $host;
}
location / {
try_files $uri $uri/ /index.html;
}
}

View File

@ -1,5 +1,24 @@
import {defineConfig} from 'vite' import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' import tailwindcss from '@tailwindcss/vite'
import {fileURLToPath,URL} from 'node:url' import { fileURLToPath, URL } from 'node:url'
export default defineConfig({plugins:[react(),tailwindcss()],resolve:{alias:{'@':fileURLToPath(new URL('./src',import.meta.url))}},server:{host:'0.0.0.0',port:1028,proxy:{'/api':{target:'http://backend:1029',changeOrigin:true},'/django-admin':{target:'http://backend:1029',changeOrigin:true}}}})
export default defineConfig({
plugins: [
react(),
tailwindcss(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
preview: {
allowedHosts: [
'boulangerie.louismazin.ovh',
'app.lefournildubocage.fr'
],
},
})