Aller au contenu principal

Variables d'environnement

Reference complete des variables d'environnement pour configurer MyTelevision API dans tous les environnements.

Vue d'ensemble

MyTelevision API utilise des variables d'environnement pour toute sa configuration. Les variables sont validees au demarrage via un schema Joi pour garantir une configuration correcte.

Hierarchie de configuration

1. Variables d'environnement (priorite la plus elevee)
2. Fichier .env (developpement uniquement)
3. Valeurs par defaut (si applicable)

Fichiers de configuration

FichierRoleSuivi Git
.envDeveloppement localNon
.env.exampleTemplate avec toutes les variablesOui
docker-compose.ymlValeurs par defaut DockerOui
src/infrastructure/config/env.validation.tsSchema de validationOui

Application

VariableDefaultDescriptionRequis
NODE_ENVdevelopmentMode d'environnement (development, staging, production)Oui
PORT3000Port du serveur APINon
API_PREFIXapi/v2Prefixe des routes APINon
API_DOCS_PATH/api/docsChemin de la documentation SwaggerNon
LOG_LEVELdebugNiveau de log (debug, info, warn, error)Non
LOG_FORMATprettyFormat de log (pretty, json pour production)Non

CORS

VariableDefaultDescriptionRequis
CORS_ORIGINS*Origins autorisees (comma-separated)Non
CORS_CREDENTIALStrueAutoriser les credentialsNon

Base de donnees (PostgreSQL)

VariableDefaultDescriptionRequis
DATABASE_URL-URL complete de connexion PostgreSQL (postgresql://user:pass@host:5432/db?schema=public)Oui
DB_HOSTlocalhostHote de la base de donneesNon
DB_PORT5432Port de la base de donneesNon
DB_USERmytvNom d'utilisateurNon
DB_PASSWORD-Mot de passeNon
DB_NAMEmytvNom de la base de donneesNon

Cache & Sessions (Redis)

VariableDefaultDescriptionRequis
REDIS_HOSTlocalhostHote RedisOui
REDIS_PORT6379Port RedisNon
REDIS_PASSWORD-Mot de passe RedisProd uniquement
REDIS_DB0Index de la base RedisNon
REDIS_TLSfalseActiver TLS (true en production)Prod uniquement

Cache applicatif

VariableDefaultDescriptionRequis
CACHE_TTL300Duree du cache en secondes (5 minutes)Non
CACHE_MAX_ITEMS1000Nombre maximum d'items en cacheNon

JWT & Authentification

VariableDefaultDescriptionRequis
JWT_SECRET-Secret pour signer les access tokens (min 32 caracteres)Oui
JWT_EXPIRATION15mDuree de validite de l'access tokenNon
JWT_REFRESH_SECRET-Secret pour signer les refresh tokens (min 32 caracteres)Oui
JWT_REFRESH_EXPIRATION7dDuree de validite du refresh tokenNon
Generation de secrets securises
# Generer un secret JWT (64 caracteres)
openssl rand -base64 48

# Ou avec Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Encryption (TOTP 2FA)

VariableDefaultDescriptionRequis
TOTP_ENCRYPTION_KEY-Cle de 32 bytes en hexadecimal (64 caracteres hex)Prod uniquement

Firebase (Authentification sociale)

VariableDefaultDescriptionRequis
FIREBASE_PROJECT_ID-ID du projet FirebaseOui
FIREBASE_PRIVATE_KEY-Cle privee du service account (format PEM, JSON-escaped)Oui
FIREBASE_CLIENT_EMAIL-Email du service accountOui
FCM_SERVER_KEY-Cle serveur FCM pour les notifications pushNon
Format de la cle privee Firebase

Dans le fichier .env, les retours a la ligne doivent etre echappes :

FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBg...\n-----END PRIVATE KEY-----\n"

Stockage (Cloudflare R2)

VariableDefaultDescriptionRequis
R2_ACCOUNT_ID-Account ID CloudflareProd uniquement
R2_ACCESS_KEY_ID-Cle d'acces R2Prod uniquement
R2_SECRET_ACCESS_KEY-Cle secrete R2Prod uniquement
R2_BUCKET_NAME-Nom du bucket R2Prod uniquement
R2_ENDPOINT-URL endpoint R2Prod uniquement
R2_PUBLIC_URL-URL publique CDN du bucketProd uniquement
PRESIGNED_URL_EXPIRY3600Duree des URLs presignees en secondes (1 heure)Non
MAX_FILE_SIZE104857600Taille max de fichier en bytes (100 MB)Non

TMDb API

VariableDefaultDescriptionRequis
TMDB_API_KEY-Cle API TMDbOui
TMDB_API_URLhttps://api.themoviedb.org/3URL de base de l'API TMDbNon
TMDB_IMAGE_BASE_URLhttps://image.tmdb.org/t/pURL de base des images TMDbNon
TMDB_DEFAULT_LANGUAGEfr-FRLangue par defaut pour les requetes TMDbNon

Streaming & Securite

VariableDefaultDescriptionRequis
STREAMING_SIGNING_SECRET-Cle HMAC pour signer les tokens de streaming (min 32 caracteres)Oui
STREAMING_AES128_KEY-Cle AES-128 pour chiffrement DRM/URLs (64 caracteres hex, 256 bits)Oui
STREAM_TOKEN_EXPIRY_HOURS24Duree de validite du token en heuresNon
STREAM_TOKEN_MAX_USES5Nombre max d'utilisations par tokenNon
STREAM_TOKEN_IP_BINDINGtrueLier le token a l'IP clientNon
Generation des cles de streaming
# STREAMING_SIGNING_SECRET (base64, min 32 chars)
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

# STREAMING_AES128_KEY (hex, 64 chars = 256 bits)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Flux d'authentification streaming (X-Stream-Token)

Le streaming securise utilise un systeme de double-token :

  1. Authorization : Bearer token JWT (authentification utilisateur)
  2. X-Stream-Token : Token de streaming (genere dynamiquement pour chaque contenu)
┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│ Login │ ──> │ Generate │ ──> │ Stream │
│ /auth/login │ │ Stream Token│ │ Content │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
v v v
accessToken POST /streaming/token GET /movies/{id}/stream
+ accessToken + accessToken
+ mediaType/mediaId + X-Stream-Token

Rate Limiting

VariableDefaultDescriptionRequis
THROTTLE_SHORT_TTL1000Fenetre courte en msNon
THROTTLE_SHORT_LIMIT3Requetes max par fenetre courteNon
THROTTLE_MEDIUM_TTL10000Fenetre moyenne en msNon
THROTTLE_MEDIUM_LIMIT20Requetes max par fenetre moyenneNon
THROTTLE_LONG_TTL60000Fenetre longue en msNon
THROTTLE_LONG_LIMIT100Requetes max par fenetre longueNon

Internationalisation (i18n)

VariableDefaultDescriptionRequis
DEFAULT_LOCALEfr_FRLocale par defautNon
SUPPORTED_LOCALESfr_FR,en_USLocales supportees (comma-separated)Non

Pagination

VariableDefaultDescriptionRequis
DEFAULT_PAGE_SIZE20Taille de page par defautNon
MAX_PAGE_SIZE100Taille de page maximaleNon

Email

VariableDefaultDescriptionRequis
EMAIL_ENABLEDfalseActiver l'envoi reel d'emailsNon
EMAIL_PROVIDERconsoleFournisseur d'email (console, sendgrid, ses)Non
EMAIL_FROM_ADDRESS[email protected]Adresse d'expeditionNon
EMAIL_FROM_NAMEMyTelevisionNom d'expeditionNon
EMAIL_VERIFICATION_EXPIRY_HOURS24Duree de validite du code de verification en heuresNon
MAX_VERIFICATION_ATTEMPTS5Max tentatives de verificationNon
RESEND_VERIFICATION_COOLDOWN_MINUTES2Delai entre renvois de code en minutesNon

Monitoring (Prometheus)

VariableDefaultDescriptionRequis
METRICS_ENABLEDtrueActiver les metriques PrometheusNon
METRICS_PATH/metricsChemin de l'endpoint metriquesNon

Multi-tenant (Systeme Account/Profile)

VariableDefaultDescriptionRequis
DEFAULT_MAX_PROFILES_PER_ACCOUNT4Max profils par compteNon
DEFAULT_MAX_DEVICES_PER_ACCOUNT5Max appareils par compteNon
DEFAULT_MAX_CONCURRENT_SESSIONS4Max sessions simultaneesNon
KIDS_DEFAULT_MAX_AGE_RATING7Rating max par defaut pour profils enfantsNon
KIDS_DEFAULT_DAILY_LIMIT_MINUTES120Limite quotidienne en minutesNon
PIN_MAX_ATTEMPTS5Max tentatives avant blocageNon
PIN_LOCKOUT_MINUTES15Duree du blocage en minutesNon

Suppression de compte (RGPD)

VariableDefaultDescriptionRequis
DELETION_RETRACTION_DAYS30Jours avant suppression definitiveNon

Synchronisation (Sources externes)

VariableDefaultDescriptionRequis
MYTV_V1_API_URLhttps://mytelevision.stream/apiURL de l'API MyTV v1 legacyNon
D5NEWS_API_URLhttps://apiv3.d5newstv.comURL de l'API D5NewsNon

Configuration par environnement

Developpement

# .env (developpement local)
NODE_ENV=development
PORT=3000

# Database (Docker)
DATABASE_URL=postgresql://mytv:mytv_password@localhost:5432/mytv?schema=public

# Redis (Docker)
REDIS_HOST=localhost
REDIS_PORT=6379

# JWT (secrets dev - PAS pour la production)
JWT_SECRET=dev-jwt-secret-minimum-32-characters-long
JWT_REFRESH_SECRET=dev-jwt-refresh-secret-minimum-32-chars

# Firebase (projet de test)
FIREBASE_PROJECT_ID=mytelevision-dev
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
FIREBASE_CLIENT_EMAIL=[email protected]

# TMDb
TMDB_API_KEY=your_tmdb_api_key

# Streaming
STREAMING_SIGNING_SECRET=dev-streaming-secret-min-32-chars-long
STREAMING_AES128_KEY=0000000000000000000000000000000000000000000000000000000000000000

Staging

NODE_ENV=staging
PORT=3000

DATABASE_URL=postgresql://app:${DB_PASSWORD}@staging-db.internal:5432/mytelevision?schema=public

REDIS_HOST=staging-redis.internal
REDIS_PORT=6379
REDIS_PASSWORD=${REDIS_PASSWORD}

JWT_SECRET=${JWT_SECRET}
JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET}

FIREBASE_PROJECT_ID=mytelevision-staging
FIREBASE_PRIVATE_KEY=${FIREBASE_PRIVATE_KEY}
FIREBASE_CLIENT_EMAIL=${FIREBASE_CLIENT_EMAIL}

R2_ACCOUNT_ID=${R2_ACCOUNT_ID}
R2_ACCESS_KEY_ID=${R2_ACCESS_KEY_ID}
R2_SECRET_ACCESS_KEY=${R2_SECRET_ACCESS_KEY}
R2_BUCKET_NAME=mytelevision-staging
R2_PUBLIC_URL=https://staging-cdn.mytelevision.com

TMDB_API_KEY=${TMDB_API_KEY}
STREAMING_SIGNING_SECRET=${STREAMING_SIGNING_SECRET}

Production

NODE_ENV=production
PORT=3000

# Connection pooling en production
DATABASE_URL=postgresql://app:${DB_PASSWORD}@prod-db-pool.internal:6432/mytelevision?schema=public&connection_limit=20

# Redis cluster avec TLS
REDIS_HOST=prod-redis.internal
REDIS_PORT=6379
REDIS_PASSWORD=${REDIS_PASSWORD}
REDIS_TLS=true

# Secrets JWT forts (generes, rotation trimestrielle)
JWT_SECRET=${JWT_SECRET}
JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET}

# Firebase (production)
FIREBASE_PROJECT_ID=mytelevision-prod
FIREBASE_PRIVATE_KEY=${FIREBASE_PRIVATE_KEY}
FIREBASE_CLIENT_EMAIL=${FIREBASE_CLIENT_EMAIL}

# R2 (production)
R2_ACCOUNT_ID=${R2_ACCOUNT_ID}
R2_ACCESS_KEY_ID=${R2_ACCESS_KEY_ID}
R2_SECRET_ACCESS_KEY=${R2_SECRET_ACCESS_KEY}
R2_BUCKET_NAME=mytelevision-prod
R2_PUBLIC_URL=https://cdn.mytelevision.com

TMDB_API_KEY=${TMDB_API_KEY}
STREAMING_SIGNING_SECRET=${STREAMING_SIGNING_SECRET}

Variables requises par profil Docker

Variabledevstagingprod
JWT_SECRETdefaultrequisrequis
JWT_REFRESH_SECRETdefaultrequisrequis
STREAMING_SIGNING_SECRETdefaultrequisrequis
CORS_ORIGINSdefaultrequisrequis

Gestion des secrets

Developpement

cp .env.example .env
# Editer .env avec vos valeurs locales

Docker Compose (Staging/Production)

# Creer les secrets
echo "your_jwt_secret" | docker secret create jwt_secret -
echo "your_db_password" | docker secret create db_password -

# Reference dans docker-compose.production.yml
secrets:
jwt_secret:
external: true
db_password:
external: true

services:
api:
secrets:
- jwt_secret
- db_password
environment:
- JWT_SECRET_FILE=/run/secrets/jwt_secret
- DB_PASSWORD_FILE=/run/secrets/db_password

Kubernetes

apiVersion: v1
kind: Secret
metadata:
name: mytelevision-secrets
type: Opaque
stringData:
JWT_SECRET: 'your-jwt-secret'
JWT_REFRESH_SECRET: 'your-refresh-secret'
DATABASE_URL: 'postgresql://...'
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: api
envFrom:
- secretRef:
name: mytelevision-secrets

Rotation des secrets

SecretFrequenceProcessus
JWT_SECRETTrimestrielleRolling update, conserver l'ancienne cle 24h
JWT_REFRESH_SECRETTrimestrielleIdem JWT_SECRET
DB_PASSWORDAnnuelleCoordonner avec le DBA
Cles R2AnnuelleCreer nouvelle, deprecier ancienne
FIREBASE_PRIVATE_KEYSi necessaireVia Firebase Console

Validation au demarrage

Schema Joi

L'API valide toutes les variables d'environnement au demarrage :

// src/infrastructure/config/env.validation.ts
export const validationSchema = Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'staging', 'production')
.default('development'),

PORT: Joi.number().default(3000),

DATABASE_URL: Joi.string().required(),

JWT_SECRET: Joi.string().min(32).required(),
JWT_REFRESH_SECRET: Joi.string().min(32).required(),

// ... autres validations
});

Regles de validation

RegleDescription
required()Obligatoire, bloque le demarrage si absente
min(32)Minimum 32 caracteres (pour les secrets)
valid(...)Doit etre une des valeurs specifiees
default(...)Valeur utilisee si non fournie
when('NODE_ENV', ...)Conditionnelle selon l'environnement

Erreurs au demarrage

Si la validation echoue, l'API affiche une erreur claire et s'arrete :

[Nest] ERROR - Config validation error: "JWT_SECRET" length must be at least 32 characters long

Troubleshooting

1. Connexion base de donnees echouee

Error: connect ECONNREFUSED 127.0.0.1:5432

Solution :

docker-compose ps
docker-compose up -d postgres

2. Connexion Redis echouee

Error: connect ECONNREFUSED 127.0.0.1:6379

Solution :

docker-compose ps
docker-compose up -d redis

3. Secret JWT trop court

Error: "JWT_SECRET" length must be at least 32 characters long

Solution :

openssl rand -base64 32

4. Format cle privee Firebase

Error: Firebase private key must be a valid PEM string

Solution :

# Dans .env, echapper les retours a la ligne :
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBg...\n-----END PRIVATE KEY-----\n"

5. R2 non configure (production)

Warning: R2 storage not configured. File uploads will fail.

Solution :

R2_ACCOUNT_ID=your_account_id
R2_ACCESS_KEY_ID=your_access_key
R2_SECRET_ACCESS_KEY=your_secret_key
R2_BUCKET_NAME=your_bucket
R2_PUBLIC_URL=https://your-cdn-url