Docker Guide
Guide complet pour la containerisation de MyTelevision API.
Vue d'ensemble
L'infrastructure Docker de MyTelevision API est concue pour etre production-grade avec :
- Multi-stage builds pour des images optimisees (< 200MB en production)
- Profiles pour differents environnements (dev/staging/prod)
- Healthchecks sur tous les services
- Security : containers non-root, pas de secrets hardcodes
- Monitoring : Prometheus, Grafana, Alertmanager
Architecture Docker
Diagramme d'Architecture
┌─────────────────────────────────────────────────────────────────────────────┐
│ Docker Host │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ mytelevision-network (bridge) │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ API │ │ │
│ │ │ :5432 │◄───►│ :6379 │◄───►│ :3000 │◄─── Clients │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ postgres │ │ redis │ │ prometheus │ │ │
│ │ │ exporter │ │ exporter │ │ :9090 │ │ │
│ │ │ :9187 │ │ :9121 │ └─────────────┘ │ │
│ │ └─────────────┘ └─────────────┘ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────┐ │ │
│ │ │ Grafana │ │ │
│ │ │ :3001 │ │ │
│ │ └─────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Prerequis
Logiciels requis
| Logiciel | Version minimum | Installation |
|---|---|---|
| Docker | 24+ | docs.docker.com |
| Docker Compose | 2.20+ | Inclus avec Docker Desktop |
| Git | 2.40+ | git-scm.com |
Verification
# Verifier les versions
docker --version # Docker version 24.x.x
docker compose version # Docker Compose version v2.x.x
# Verifier que Docker fonctionne
docker run --rm hello-world
Dockerfile Multi-stage
┌──────────────────────────────────────────────────────────────┐
│ Stage 1: deps │
│ ├── Base: node:20-alpine │
│ ├── Installe: libc6-compat, openssl │
│ └── Execute: npm ci (dependances) │
├──────────────────────────────────────────────────────────────┤
│ Stage 2: builder │
│ ├── Base: node:20-alpine │
│ ├── Copie: node_modules depuis deps │
│ ├── Execute: prisma generate │
│ ├── Execute: npm run build │
│ └── Execute: npm prune --omit=dev │
├──────────────────────────────────────────────────────────────┤
│ Stage 3: runner (Production) │
│ ├── Base: node:20-alpine │
│ ├── User: nestjs (UID 1001) - non-root │
│ ├── Copie: dist/, node_modules/, prisma/ │
│ ├── Healthcheck: wget /api/v2/health/live │
│ └── CMD: node dist/main │
└──────────────────────────────────────────────────────────────┘
Taille d'image cible
| Stage | Taille estimee |
|---|---|
| deps | ~500MB (temporaire) |
| builder | ~800MB (temporaire) |
| runner | < 200MB (production) |
Exemple Dockerfile
# ======================
# Stage 1: Dependencies
# ======================
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# ======================
# Stage 2: Builder
# ======================
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
RUN npx prisma generate
# ======================
# Stage 3: Production
# ======================
FROM node:20-alpine AS production
WORKDIR /app
# Security: non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nestjs -u 1001
# Copy built files
COPY /app/node_modules ./node_modules
COPY /app/dist ./dist
COPY /app/node_modules/.prisma ./node_modules/.prisma
COPY /app/prisma ./prisma
# Security hardening
USER nestjs
EXPOSE 3000
# Health check
HEALTHCHECK \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/v2/health/live || exit 1
CMD ["node", "dist/main.js"]
Demarrage rapide
Premier demarrage (< 10 minutes)
# 1. Cloner le repository
git clone https://github.com/XKS-MYTV4JS/mytelevision-restfullapijsv4.git
cd mytelevision-restfullapijsv4
# 2. Copier les variables d'environnement
cp .env.example .env
# 3. Demarrer l'environnement de developpement
docker compose up -d
# 4. Verifier que tous les services sont healthy
docker compose ps
# 5. Tester l'API
curl http://localhost:3000/api/v2/health/live
Resultat attendu
{
"status": "ok",
"timestamp": "2025-12-17T10:00:00.000Z"
}
Profiles Docker
Matrice des Profiles
| Profile | Services | Usage | Commande |
|---|---|---|---|
dev | API + DB + Redis | Developpement local | docker compose --profile dev up -d |
staging | API + DB + Redis | Pre-production | docker compose --profile staging up -d |
prod | API + DB + Redis | Production | docker compose --profile prod up -d |
| (aucun) | API legacy + DB + Redis | Retro-compatible | docker compose up -d |
Differences entre profiles
| Configuration | dev | staging | prod |
|---|---|---|---|
NODE_ENV | development | staging | production |
LOG_LEVEL | debug | info | warn |
JWT_EXPIRES_IN | 1d | 15m | 15m |
THROTTLE_LIMIT | 1000 | 100 | 100 |
restart | unless-stopped | unless-stopped | always |
| Resource limits | Non | Non | CPU: 1.0, RAM: 512M |
Utilisation avec monitoring
# Development sans monitoring
docker compose --profile dev up -d
# Staging avec monitoring
docker compose --profile staging -f docker-compose.yml -f docker-compose.monitoring.yml up -d
# Production avec monitoring
docker compose --profile prod -f docker-compose.yml -f docker-compose.monitoring.yml up -d
Services
Services de base
| Service | Image | Port | Healthcheck | Volume |
|---|---|---|---|---|
postgres | postgres:16-alpine | 5432 | pg_isready | mytv-postgres-data |
redis | redis:7-alpine | 6379 | redis-cli ping | mytv-redis-data |
api / api-{profile} | mytv-api:latest | 3000 | wget /health/live | - |
migration | mytv-api:builder | - | - | - |
Services de monitoring (staging/prod)
| Service | Image | Port | Description |
|---|---|---|---|
prometheus | prom/prometheus:v2.47.0 | 9090 | Collecte de metriques |
grafana | grafana/grafana:10.2.0 | 3001 | Dashboards |
alertmanager | prom/alertmanager:v0.26.0 | 9093 | Gestion des alertes |
node-exporter | prom/node-exporter:v1.6.1 | 9100 | Metriques host |
postgres-exporter | prometheuscommunity/postgres-exporter:v0.15.0 | 9187 | Metriques PostgreSQL |
redis-exporter | oliver006/redis_exporter:v1.55.0 | 9121 | Metriques Redis |
cadvisor | gcr.io/cadvisor/cadvisor:v0.47.2 | 8080 | Metriques containers |
Docker Compose Development
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- '3000:3000'
environment:
- NODE_ENV=development
- DATABASE_URL=postgresql://mytv:password@postgres:5432/mytv
- REDIS_HOST=redis
depends_on:
- postgres
- redis
volumes:
- ./src:/app/src # Hot reload
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: mytv
POSTGRES_PASSWORD: password
POSTGRES_DB: mytv
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- '5432:5432'
redis:
image: redis:7-alpine
command: redis-server --requirepass password
ports:
- '6379:6379'
volumes:
postgres_data:
Docker Compose Production
# docker-compose.production.yml
version: '3.8'
services:
api:
image: ${DOCKER_REGISTRY}/mytv-api:${VERSION}
deploy:
replicas: 3
resources:
limits:
cpus: '1'
memory: 1G
secrets:
- jwt_secret
- db_password
environment:
- NODE_ENV=production
- DATABASE_URL_FILE=/run/secrets/db_url
secrets:
jwt_secret:
external: true
db_password:
external: true
Commandes courantes
Gestion des services
# ═══════════════════════════════════════════════════════
# DEMARRAGE
# ═══════════════════════════════════════════════════════
# Demarrer tous les services (mode legacy)
docker compose up -d
# Demarrer avec un profile specifique
docker compose --profile dev up -d
docker compose --profile staging up -d
docker compose --profile prod up -d
# Demarrer avec monitoring
docker compose --profile staging -f docker-compose.yml -f docker-compose.monitoring.yml up -d
# ═══════════════════════════════════════════════════════
# ARRET
# ═══════════════════════════════════════════════════════
# Arreter tous les services
docker compose down
# Arreter et supprimer les volumes (perte de donnees)
docker compose down -v
# ═══════════════════════════════════════════════════════
# LOGS
# ═══════════════════════════════════════════════════════
# Voir tous les logs
docker compose logs -f
# Logs d'un service specifique
docker compose logs -f api
docker compose logs -f postgres
# Logs avec timestamps
docker compose logs -f --timestamps
# ═══════════════════════════════════════════════════════
# STATUT
# ═══════════════════════════════════════════════════════
# Voir l'etat des services
docker compose ps
# Voir l'utilisation des ressources
docker stats
# ═══════════════════════════════════════════════════════
# BUILD
# ═══════════════════════════════════════════════════════
# Rebuild l'image API
docker compose build api
# Rebuild sans cache
docker compose build --no-cache api
# Pull les dernieres images
docker compose pull
Base de donnees
# Appliquer les migrations
docker compose exec api npx prisma migrate deploy
# Ouvrir Prisma Studio
docker compose exec api npx prisma studio
# Generer le client Prisma
docker compose exec api npx prisma generate
# Reset de la base (destructif)
docker compose exec api npx prisma migrate reset
# Shell PostgreSQL
docker compose exec postgres psql -U mytelevision -d mytelevision
# Shell Redis
docker compose exec redis redis-cli -a redis_secret
Nettoyage
# Supprimer les containers arretes
docker container prune
# Supprimer les images non utilisees
docker image prune
# Supprimer les volumes non utilises (attention)
docker volume prune
# Nettoyage complet (destructif)
docker system prune -af
Troubleshooting
Le container API ne demarre pas
# Verifier les logs
docker compose logs api
# Causes possibles:
# 1. Base de donnees non prete -> attendre healthcheck
# 2. Variables d'environnement manquantes -> verifier .env
# 3. Port deja utilise -> changer PORT dans .env
Erreur de connexion a la base de donnees
# Verifier que PostgreSQL est healthy
docker compose ps postgres
# Tester la connexion
docker compose exec postgres pg_isready -U mytelevision
# Verifier DATABASE_URL
docker compose exec api printenv DATABASE_URL
Erreur de connexion Redis
# Verifier que Redis est healthy
docker compose ps redis
# Tester la connexion
docker compose exec redis redis-cli -a redis_secret ping
# Verifier les variables
docker compose exec api printenv REDIS_HOST REDIS_PASSWORD
Image trop volumineuse
# Verifier la taille
docker images | grep mytv
# Rebuild avec optimisation
docker compose build --no-cache api
# Verifier les layers
docker history mytelevision-api:latest
Diagnostic complet
#!/bin/bash
# Script de diagnostic
echo "=== Docker Version ==="
docker --version
docker compose version
echo "=== Services Status ==="
docker compose ps
echo "=== Container Health ==="
docker inspect --format='{{.Name}}: {{.State.Health.Status}}' $(docker compose ps -q) 2>/dev/null
echo "=== Resource Usage ==="
docker stats --no-stream
echo "=== Recent Logs (last 50 lines) ==="
docker compose logs --tail=50
Securite
Bonnes pratiques appliquees
| Pratique | Implementation |
|---|---|
| User non-root | UID 1001 (nestjs) |
| Pas de secrets hardcodes | Variables d'environnement via .env |
| Image minimale | Alpine Linux (~5MB base) |
| Healthchecks | Tous les services |
| Network isole | Bridge network dedie |
| Labels OCI | Metadonnees standard |
Verifications de securite
# Scanner l'image avec Trivy
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image mytelevision-api:latest
# Verifier l'utilisateur du container
docker compose exec api whoami
# Resultat attendu: nestjs
# Verifier les permissions
docker compose exec api ls -la /app
Variables sensibles
| Variable | Production | Stockage recommande |
|---|---|---|
JWT_SECRET | Obligatoire (64+ chars) | Vault / Docker Secrets |
DB_PASSWORD | Obligatoire | Vault / Docker Secrets |
REDIS_PASSWORD | Obligatoire | Vault / Docker Secrets |
R2_SECRET_ACCESS_KEY | Obligatoire | Vault / Docker Secrets |
Ports utilises
| Port | Service | Description |
|---|---|---|
| 3000 | API | API REST principale |
| 5432 | PostgreSQL | Base de donnees |
| 6379 | Redis | Cache |
| 3001 | Grafana | Dashboards |
| 9090 | Prometheus | Metriques |
| 9093 | Alertmanager | Alertes |
| 9100 | Node Exporter | Metriques host |
| 9121 | Redis Exporter | Metriques Redis |
| 9187 | Postgres Exporter | Metriques PostgreSQL |
| 8080 | cAdvisor | Metriques containers |
Fichiers de configuration
docker/
├── postgres/
│ └── init.sql # Script d'initialisation DB
monitoring/
├── prometheus/
│ ├── prometheus.yml # Configuration Prometheus
│ └── rules/
│ └── alerts.yml # Regles d'alerting
├── grafana/
│ ├── provisioning/
│ │ ├── datasources/ # Sources de donnees
│ │ └── dashboards/ # Provisioning dashboards
│ └── dashboards/ # Fichiers JSON des dashboards
└── alertmanager/
└── alertmanager.yml # Configuration Alertmanager