Aller au contenu principal

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

LogicielVersion minimumInstallation
Docker24+docs.docker.com
Docker Compose2.20+Inclus avec Docker Desktop
Git2.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

StageTaille 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 --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder /app/prisma ./prisma

# Security hardening
USER nestjs
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
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

ProfileServicesUsageCommande
devAPI + DB + RedisDeveloppement localdocker compose --profile dev up -d
stagingAPI + DB + RedisPre-productiondocker compose --profile staging up -d
prodAPI + DB + RedisProductiondocker compose --profile prod up -d
(aucun)API legacy + DB + RedisRetro-compatibledocker compose up -d

Differences entre profiles

Configurationdevstagingprod
NODE_ENVdevelopmentstagingproduction
LOG_LEVELdebuginfowarn
JWT_EXPIRES_IN1d15m15m
THROTTLE_LIMIT1000100100
restartunless-stoppedunless-stoppedalways
Resource limitsNonNonCPU: 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

ServiceImagePortHealthcheckVolume
postgrespostgres:16-alpine5432pg_isreadymytv-postgres-data
redisredis:7-alpine6379redis-cli pingmytv-redis-data
api / api-{profile}mytv-api:latest3000wget /health/live-
migrationmytv-api:builder---

Services de monitoring (staging/prod)

ServiceImagePortDescription
prometheusprom/prometheus:v2.47.09090Collecte de metriques
grafanagrafana/grafana:10.2.03001Dashboards
alertmanagerprom/alertmanager:v0.26.09093Gestion des alertes
node-exporterprom/node-exporter:v1.6.19100Metriques host
postgres-exporterprometheuscommunity/postgres-exporter:v0.15.09187Metriques PostgreSQL
redis-exporteroliver006/redis_exporter:v1.55.09121Metriques Redis
cadvisorgcr.io/cadvisor/cadvisor:v0.47.28080Metriques 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

PratiqueImplementation
User non-rootUID 1001 (nestjs)
Pas de secrets hardcodesVariables d'environnement via .env
Image minimaleAlpine Linux (~5MB base)
HealthchecksTous les services
Network isoleBridge network dedie
Labels OCIMetadonnees 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

VariableProductionStockage recommande
JWT_SECRETObligatoire (64+ chars)Vault / Docker Secrets
DB_PASSWORDObligatoireVault / Docker Secrets
REDIS_PASSWORDObligatoireVault / Docker Secrets
R2_SECRET_ACCESS_KEYObligatoireVault / Docker Secrets

Ports utilises

PortServiceDescription
3000APIAPI REST principale
5432PostgreSQLBase de donnees
6379RedisCache
3001GrafanaDashboards
9090PrometheusMetriques
9093AlertmanagerAlertes
9100Node ExporterMetriques host
9121Redis ExporterMetriques Redis
9187Postgres ExporterMetriques PostgreSQL
8080cAdvisorMetriques 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