Guide Docker¶
Ce guide explique comment utiliser Docker pour développer et déployer l'application.
Architecture Docker¶
L'application est composée de deux services containerisés :
- Backend : API FastAPI (Python 3.13)
- Frontend : Application Next.js (Node.js 20)
Les services communiquent via un réseau Docker dédié.
Démarrage rapide¶
Prérequis¶
- Docker 20.10+
- Docker Compose 2.0+
Commandes Make¶
# Build et démarrage (tout-en-un)
make docker-deploy
# Ou étape par étape
make docker-build # Build des images
make docker-up # Démarrage des conteneurs
make docker-logs # Voir les logs
make docker-down # Arrêt des conteneurs
Dockerfiles¶
Backend : Dockerfile.backend¶
FROM python:3.13-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
WORKDIR /app
COPY uv.lock pyproject.toml ./
RUN uv sync --frozen --no-install-project
COPY . /app
RUN uv sync --frozen
ENV PYTHONUNBUFFERED=1
EXPOSE 8000
CMD ["uv", "run", "uvicorn", "backend.app:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
Caractéristiques :
- Image légère python:3.13-slim
- Utilisation de uv pour une installation rapide
- Hot-reload activé en développement
- Variables d'environnement passées au runtime (sécurisé)
Frontend : Dockerfile.frontend¶
Build multi-stage pour optimiser la taille de l'image :
- Stage deps : Installation des dépendances
- Stage builder : Build de l'application Next.js
- Stage runner : Image de production minimale
Caractéristiques :
- Images Alpine légères (~150MB final)
- Utilisateur non-root pour la sécurité
- Mode standalone Next.js
- Variables NEXT_PUBLIC_* injectées au build
Docker Compose¶
Configuration¶
services:
backend:
build:
context: .
dockerfile: Dockerfile.backend
ports:
- "8000:8000"
environment:
- NOTION_TOKEN=${NOTION_TOKEN}
- DATABASE_ID=${DATABASE_ID}
- GCS_URI=${GCS_URI}
- GOOGLE_APPLICATION_CREDENTIALS=/app/credentials.json
volumes:
- ./gcs-credentials.json:/app/credentials.json:ro
frontend:
build:
context: .
dockerfile: Dockerfile.frontend
args:
- NEXT_PUBLIC_API_URL=http://localhost:8000
ports:
- "3000:3000"
depends_on:
- backend
Services disponibles¶
Une fois démarrés, les services sont accessibles sur :
- 🌐 Frontend : http://localhost:3000
- 🔌 Backend API : http://localhost:8000
- 📚 Documentation API : http://localhost:8000/docs
Variables d'environnement¶
Fichier .env¶
Créez un fichier .env à la racine :
# .env
NOTION_TOKEN=secret_xxxxxxxxxxxxx
DATABASE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# Google Cloud Storage
GCS_URI=gs://notion-dataascode/data_leads
HMAC_KEY=GOOG1EXXX...
HMAC_SECRET=your-hmac-secret
# Observabilité
LOGFIRE_TOKEN=logfire_xxxxxxxxxxxxx
Docker Compose charge automatiquement ce fichier.
Credentials GCS¶
Placez votre fichier de credentials GCS à la racine du projet :
# Le fichier gcs-credentials.json doit être à la racine
cp /chemin/vers/votre/credentials.json ./gcs-credentials.json
Sécurité
Assurez-vous que gcs-credentials.json est dans le .gitignore pour ne jamais le committer.
Build args vs ENV¶
Sécurité
- ✅ Utilisez
ENVau runtime pour les secrets - ❌ N'utilisez jamais
ARGpour les secrets (visible dans l'historique Docker)
Backend : Secrets passés via environment au runtime
environment:
- NOTION_TOKEN=${NOTION_TOKEN} # ✅ Sécurisé
- GCS_URI=${GCS_URI} # ✅ Pas un secret
- GOOGLE_APPLICATION_CREDENTIALS=/app/credentials.json # ✅ Chemin dans le conteneur
volumes:
- ./gcs-credentials.json:/app/credentials.json:ro # ✅ Monté en lecture seule
Frontend : URL de l'API passée via build args (pas de secret)
Volumes Docker¶
Backend¶
Le fichier de credentials GCS est monté en lecture seule (:ro) dans le conteneur.
Stockage des données
Les données Delta Lake sont maintenant stockées sur Google Cloud Storage (GCS) et non plus localement. Le montage d'un volume pour data_leads n'est plus nécessaire.
Frontend¶
Pas de volume nécessaire car Next.js est compilé dans l'image.
Health Checks¶
Les services ont des health checks configurés :
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8000/docs"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Vérifier le statut :
Réseaux¶
Les services communiquent via un réseau bridge dédié :
Logs¶
Voir les logs¶
# Tous les services
make docker-logs
# Service spécifique
docker logs dataascode-backend
docker logs dataascode-frontend
# Follow mode
docker logs -f dataascode-backend
Logs structurés avec Logfire¶
Le backend utilise Logfire + Loguru pour des logs structurés et de l'observabilité :
2025-10-26 15:30:12 | INFO | 📊 Starting weekly aggregation for columns: [...]
2025-10-26 15:30:13 | INFO | ✅ Weekly aggregation completed: 24 weeks returned
Visualisation dans Logfire : - Dashboard temps réel : https://logfire.pydantic.dev - Traces distribuées des requêtes - Métriques de performance - Recherche et filtrage avancés
Debugging¶
Accéder à un conteneur¶
# Backend
docker exec -it dataascode-backend /bin/sh
uv run python
# Frontend
docker exec -it dataascode-frontend /bin/sh
Rebuild après modifications¶
# Rebuild complet
make docker-build
# Rebuild sans cache
docker-compose build --no-cache
# Rebuild un seul service
docker-compose build backend
Optimisations¶
Cache Docker¶
Les Dockerfiles utilisent des layers cachés pour accélérer les builds :
- Copie des fichiers de dépendances d'abord
- Installation des dépendances (mise en cache)
- Copie du code source (invalide le cache seulement si le code change)
.dockerignore¶
Des fichiers .dockerignore spécifiques excluent les fichiers inutiles :
Dockerfile.backend.dockerignore: Exclutfrontend/Dockerfile.frontend.dockerignore: Exclutbackend/
Taille des images¶
# Voir la taille des images
docker images | grep dataascode
# Résultats typiques
dataascode-backend ~500MB
dataascode-frontend ~150MB
Production¶
Build pour la production¶
# Frontend avec URL API personnalisée
docker-compose build \
--build-arg NEXT_PUBLIC_API_URL=https://api.example.com \
frontend
Docker Compose production¶
Créez un docker-compose.prod.yml :
services:
backend:
restart: always
command: ["uv", "run", "uvicorn", "backend.app:app", "--host", "0.0.0.0", "--port", "8000"]
# Sans --reload
frontend:
restart: always
environment:
- NODE_ENV=production
Troubleshooting¶
Port déjà utilisé¶
# Erreur : bind: address already in use
# Trouver le processus
lsof -i :3000
lsof -i :8000
# Arrêter le processus ou changer le port dans docker-compose.yml
Conteneur ne démarre pas¶
Build échoue¶
Commandes utiles¶
# Statut des conteneurs
docker ps
# Arrêter tout
docker-compose down
# Arrêter et supprimer les volumes
docker-compose down -v
# Nettoyer tout
docker system prune -a --volumes
# Voir l'utilisation des ressources
docker stats
Prochaines étapes¶
- API Backend : Utiliser l'API
- Architecture : Comprendre l'architecture