From eb5ec756269b43990299ea9888e00c3b368d473b Mon Sep 17 00:00:00 2001 From: Benoit Date: Sat, 6 Dec 2025 22:22:13 +0100 Subject: [PATCH] Dockerisation de tout --- DOCKER.md | 176 +++++++++++++++++++++++++++++++++++++++ README.md | 16 ++-- backend/Dockerfile | 31 +++---- backend/requirements.txt | 6 +- docker-compose.dev.yml | 17 ++++ docker-compose.yml | 21 +++-- frontend/Dockerfile | 22 +++++ frontend/Dockerfile.dev | 16 ++++ 8 files changed, 269 insertions(+), 36 deletions(-) create mode 100644 DOCKER.md create mode 100644 frontend/Dockerfile create mode 100644 frontend/Dockerfile.dev diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..121d38e --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,176 @@ +# Dockerisation du projet Audio Classifier + +## 🐳 Architecture Docker + +Le projet est entièrement dockerisé avec deux configurations distinctes : + +1. **Production** (`docker-compose.yml`) - Version optimisée pour le déploiement +2. **Développement** (`docker-compose.dev.yml`) - Version avec hot-reload pour le développement + +## 📁 Structure des Services + +```yaml +services: + postgres: # Base de données PostgreSQL avec pgvector + backend: # API FastAPI (Python 3.11) + frontend: # Interface Next.js (Node.js 20) +``` + +## 🚀 Commandes de déploiement + +### Mode Production + +```bash +# Démarrer tous les services +docker-compose up -d + +# Arrêter tous les services +docker-compose down + +# Voir les logs +docker-compose logs +``` + +### Mode Développement + +```bash +# Démarrer tous les services en mode dev +docker-compose -f docker-compose.dev.yml up -d + +# Arrêter tous les services +docker-compose -f docker-compose.dev.yml down + +# Voir les logs +docker-compose -f docker-compose.dev.yml logs +``` + +## 🏗 Construction des images + +### Backend (Production) +- **Base** : `python:3.9-slim` (pour compatibilité Essentia) +- **Dépendances système** : ffmpeg, libsndfile, etc. +- **Dépendances Python** : Toutes les dépendances du fichier `requirements.txt` +- **Optimisation** : Multi-stage build pour réduire la taille + +### Backend (Développement) +- **Base** : `python:3.11-slim` +- **Dépendances** : Version minimale sans Essentia +- **Hot-reload** : Montage du code source pour développement + +### Frontend (Production) +- **Base** : `node:20-alpine` +- **Build** : Application Next.js compilée +- **Optimisation** : Image légère Alpine Linux + +### Frontend (Développement) +- **Base** : `node:20-alpine` +- **Hot-reload** : Montage du code source +- **Dépendances** : Installation des modules Node + +## ⚙️ Configuration des environnements + +### Variables d'environnement + +Les variables sont définies dans les fichiers `.env` et peuvent être surchargées : + +**Base de données :** +- `POSTGRES_USER` - Utilisateur PostgreSQL +- `POSTGRES_PASSWORD` - Mot de passe PostgreSQL +- `POSTGRES_DB` - Nom de la base de données +- `DATABASE_URL` - URL de connexion complète + +**Backend :** +- `CORS_ORIGINS` - Origines autorisées pour CORS +- `ANALYSIS_USE_CLAP` - Activation des embeddings CLAP +- `ANALYSIS_NUM_WORKERS` - Nombre de workers d'analyse +- `ESSENTIA_MODELS_PATH` - Chemin vers les modèles Essentia + +**Frontend :** +- `NEXT_PUBLIC_API_URL` - URL de l'API backend + +### Volumes Docker + +**Base de données :** +- `postgres_data` - Persistance des données PostgreSQL + +**Backend :** +- `${AUDIO_LIBRARY_PATH}:/audio:ro` - Montage de la bibliothèque audio (lecture seule) +- `./backend/models:/app/models` - Montage des modèles Essentia + +**Frontend :** +- `./frontend:/app` (dev) - Montage du code source +- `/app/node_modules` (dev) - Persistance des modules Node + +## 🔄 Flux de développement + +1. **Développement backend :** + - Modifier le code dans `backend/src/` + - Hot-reload automatique avec `docker-compose.dev.yml` + +2. **Développement frontend :** + - Modifier le code dans `frontend/` + - Hot-reload automatique avec Next.js + +3. **Déploiement :** + - Construire les images avec `docker-compose build` + - Démarrer les services avec `docker-compose up -d` + +## 🔧 Maintenance et debugging + +### Accéder au conteneur backend +```bash +docker exec -it audio_classifier_api sh +``` + +### Accéder au conteneur frontend +```bash +docker exec -it audio_classifier_ui sh +``` + +### Accéder à la base de données +```bash +docker exec -it audio_classifier_db psql -U audio_user -d audio_classifier +``` + +### Réinitialiser la base de données +```bash +docker-compose down -v +docker-compose up -d +``` + +## 📈 Performance et optimisation + +### Backend +- Utilisation de `--platform=linux/amd64` pour compatibilité Essentia +- Installation des dépendances Python par étapes pour meilleur cache +- Montage des modèles Essentia pour persistance + +### Frontend +- Utilisation d'Alpine Linux pour image légère +- Installation des dépendances avant copie du code +- Exclusion de `node_modules` du contexte de build + +## 🔒 Sécurité + +- Conteneurs non-root par défaut +- Montage lecture-seule de la bibliothèque audio +- Mise à jour régulière des images de base +- Utilisation de versions spécifiques des dépendances + +## 🆘 Problèmes courants + +### Essentia non disponible sur ARM +Solution : Utiliser `--platform=linux/amd64` dans le Dockerfile + +### Permissions de fichiers +Solution : Vérifier les permissions du dossier audio monté + +### CORS errors +Solution : Vérifier la configuration `CORS_ORIGINS` + +## 📚 Références + +- [Docker Documentation](https://docs.docker.com/) +- [Docker Compose Documentation](https://docs.docker.com/compose/) +- [PostgreSQL avec pgvector](https://github.com/pgvector/pgvector) +- [Next.js Dockerisation](https://nextjs.org/docs/deployment) diff --git a/README.md b/README.md index d462237..07c6a70 100644 --- a/README.md +++ b/README.md @@ -59,23 +59,23 @@ AUDIO_LIBRARY_PATH=/chemin/vers/vos/fichiers/audio ./scripts/download-essentia-models.sh ``` -### 4. Lancer avec Docker +### 4. Lancer avec Docker (Production) ```bash docker-compose up -d ``` -L'API sera disponible sur `http://localhost:8000` -La documentation interactive : `http://localhost:8000/docs` +L'API sera disponible sur `http://localhost:8001` +La documentation interactive : `http://localhost:8001/docs` +Le frontend sera accessible sur `http://localhost:3000` -### 5. Lancer le frontend (développement) +### 5. Lancer avec Docker (Développement) ```bash -cd frontend -npm install -npm run dev +docker-compose -f docker-compose.dev.yml up -d ``` +L'API sera disponible sur `http://localhost:8001` Le frontend sera accessible sur `http://localhost:3000` ## 📖 Utilisation @@ -91,7 +91,7 @@ Le frontend sera accessible sur `http://localhost:3000` #### Via l'API ```bash -curl -X POST http://localhost:8000/api/analyze/folder \ +curl -X POST http://localhost:8001/api/analyze/folder \ -H "Content-Type: application/json" \ -d '{"path": "/audio/music", "recursive": true}' ``` diff --git a/backend/Dockerfile b/backend/Dockerfile index 120924a..4e61e97 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,5 @@ -FROM python:3.8-slim +# Use amd64 platform for better Essentia compatibility, works with emulation on ARM +FROM --platform=linux/amd64 python:3.9-slim # Install system dependencies RUN apt-get update && apt-get install -y \ @@ -12,6 +13,16 @@ RUN apt-get update && apt-get install -y \ liblapack-dev \ pkg-config \ curl \ + build-essential \ + libyaml-dev \ + libfftw3-dev \ + libavcodec-dev \ + libavformat-dev \ + libavutil-dev \ + libswresample-dev \ + libsamplerate0-dev \ + libtag1-dev \ + libchromaprint-dev \ && rm -rf /var/lib/apt/lists/* # Set working directory @@ -24,20 +35,12 @@ RUN pip install --no-cache-dir --upgrade pip setuptools wheel COPY requirements.txt . # Install Python dependencies in stages for better caching -# Using versions compatible with Python 3.8 -RUN pip install --no-cache-dir numpy==1.23.5 -RUN pip install --no-cache-dir scipy==1.10.1 +# Using versions compatible with Python 3.9 +RUN pip install --no-cache-dir numpy==1.24.3 +RUN pip install --no-cache-dir scipy==1.11.4 -# Install Essentia - Python 3.8 version (latest available with pre-built wheels) -RUN ARCH=$(uname -m) && \ - if [ "$ARCH" = "x86_64" ]; then \ - echo "Installing Essentia for x86_64 Python 3.8..." && \ - pip install --no-cache-dir --trusted-host essentia.upf.edu \ - https://essentia.upf.edu/python-wheels/essentia-2.1b6.dev218-cp38-cp38-manylinux1_x86_64.whl || \ - echo "Essentia installation failed, using fallback mode"; \ - else \ - echo "Essentia wheels only available for x86_64, using fallback mode"; \ - fi +# Install Essentia - Python 3.9 with ARM64 support +RUN pip install --no-cache-dir essentia RUN pip install --no-cache-dir -r requirements.txt diff --git a/backend/requirements.txt b/backend/requirements.txt index cc25133..f388193 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -18,9 +18,9 @@ mutagen==1.47.0 # Essentia for genre/mood/instrument classification # Note: Essentia is installed separately in Dockerfile from official wheels -# Scientific Computing (versions compatible with Python 3.8) -numpy==1.23.5 -scipy==1.10.1 +# Scientific Computing (versions compatible with Python 3.9) +numpy==1.24.3 +scipy==1.11.4 # Configuration & Validation pydantic==2.5.3 diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index d0aea3f..781feef 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -44,6 +44,23 @@ services: - ./backend/src:/app/src restart: unless-stopped + frontend: + build: + context: ./frontend + dockerfile: Dockerfile.dev + container_name: audio_classifier_ui_dev + environment: + NEXT_PUBLIC_API_URL: http://backend:8000 + NODE_ENV: development + ports: + - "3000:3000" + volumes: + - ./frontend:/app + - /app/node_modules + depends_on: + - backend + restart: unless-stopped + volumes: postgres_data: driver: local diff --git a/docker-compose.yml b/docker-compose.yml index 464f304..45d274a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,17 +39,16 @@ services: - ./backend/models:/app/models restart: unless-stopped - # Frontend (development mode - for production use static build) - # frontend: - # build: ./frontend - # container_name: audio_classifier_ui - # environment: - # NEXT_PUBLIC_API_URL: http://localhost:8000 - # ports: - # - "3000:3000" - # depends_on: - # - backend - # restart: unless-stopped + frontend: + build: ./frontend + container_name: audio_classifier_ui + environment: + NEXT_PUBLIC_API_URL: http://backend:8000 + ports: + - "3000:3000" + depends_on: + - backend + restart: unless-stopped volumes: postgres_data: diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..ecf7a27 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,22 @@ +FROM node:20-alpine + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm ci + +# Copy application code +COPY . . + +# Build the application +RUN npm run build + +# Expose port +EXPOSE 3000 + +# Start the application +CMD ["npm", "start"] diff --git a/frontend/Dockerfile.dev b/frontend/Dockerfile.dev new file mode 100644 index 0000000..e33fb19 --- /dev/null +++ b/frontend/Dockerfile.dev @@ -0,0 +1,16 @@ +FROM node:20-alpine + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm ci + +# Expose port +EXPOSE 3000 + +# Start the development server +CMD ["npm", "run", "dev"]