Configuration - Variables d'Environnement¶
Date: 2026-01-04
Fichier: .env (copier depuis .env.example)
Fichier de Configuration¶
# Créer le fichier .env
cp .env.example .env
# Éditer les valeurs
nano .env
# ⚠️ IMPORTANT: Changer TOUS les mots de passe en production
Variables par Catégorie¶
1. Base de Données¶
# Hôte du serveur MariaDB
# - Docker: "db" (nom du service)
# - Externe: IP ou hostname
DB_HOST=db
# Port MariaDB
DB_PORT=3306
# Nom de la base de données
DB_NAME=urbafix
# Utilisateur applicatif (privilèges limités)
DB_USER=urbafix_user
# Mot de passe utilisateur
# ⚠️ PRODUCTION: Générer mot de passe fort 32+ caractères
DB_PASSWORD=changez_ce_mot_de_passe_2024
# Mot de passe root MySQL (administration)
# Utilisé pour: backups, migrations, phpMyAdmin
# ⚠️ PRODUCTION: Différent de DB_PASSWORD
MYSQL_ROOT_PASSWORD=changez_ce_mot_de_passe_root_2024
Génération mots de passe forts :
# Linux
openssl rand -base64 32
# Docker
docker run --rm alpine sh -c "head -c 32 /dev/urandom | base64"
2. Application¶
# URL publique de l'application (sans slash final)
# Utilisée pour: liens emails, redirections, CORS
APP_URL=http://localhost:8080
# Environnement d'exécution
# Valeurs: dev, staging, production
# Impact: error reporting, debug mode
APP_ENV=production
# Mode debug
# true: Affiche erreurs détaillées (dev seulement)
# false: Logs errors, affiche page générique (production)
# ⚠️ PRODUCTION: TOUJOURS false
APP_DEBUG=false
Valeurs recommandées par environnement :
| Env | APP_URL | APP_ENV | APP_DEBUG |
|---|---|---|---|
| Dev | http://localhost:8080 |
dev | true |
| Staging | https://staging.urbafix.fr |
staging | false |
| Production | https://urbafix.fr |
production | false |
3. Ports Docker¶
# Port web (PHP + Nginx)
# Le service web sera accessible sur http://localhost:${WEB_PORT}
WEB_PORT=8080
# Port base de données (exposition externe)
# ⚠️ PRODUCTION: Commenter cette ligne (ne pas exposer)
# Utile en dev pour clients MySQL externes (Sequel Pro, DBeaver)
DB_EXTERNAL_PORT=3306
# Port phpMyAdmin
# ⚠️ PRODUCTION: Ne pas activer (--profile admin)
PHPMYADMIN_PORT=8081
# Port Redis (exposition externe)
# ⚠️ PRODUCTION: Commenter cette ligne (ne pas exposer)
# Utile en dev pour Redis GUI (RedisInsight, Medis)
REDIS_PORT=6379
Sécurité Production :
# .env.production
WEB_PORT=8080
# DB_EXTERNAL_PORT=3306 ← Commenté
# PHPMYADMIN_PORT=8081 ← Commenté
# REDIS_PORT=6379 ← Commenté
4. Redis (Global)¶
# Mot de passe Redis (partagé par sessions/cache/queue)
# ⚠️ OBLIGATOIRE en production (>= 32 caractères)
# Redis refuse connexions sans password par défaut
REDIS_PASSWORD=changez_ce_mot_de_passe_redis
Génération :
Note : Les subsystèmes (sessions, cache, queue) héritent de ce password sauf si surchargé.
5. Sécurité¶
# Clé secrète pour sessions et chiffrement
# Utilisée pour: CSRF tokens, session ID generation
# ⚠️ PRODUCTION: Générer clé aléatoire >= 64 caractères
APP_SECRET_KEY=changez_cette_cle_secrete_aleatoire_longue
# Durée de vie des sessions (secondes)
# 3600 = 1 heure
# 7200 = 2 heures
# 86400 = 24 heures
SESSION_LIFETIME=3600
Génération APP_SECRET_KEY :
6. Uploads¶
# Taille maximale des uploads (Mo)
# Doit correspondre à:
# - php.ini: upload_max_filesize, post_max_size
# - nginx.conf: client_max_body_size
UPLOAD_MAX_SIZE_MB=64
# Extensions autorisées - Photos (séparées par virgules)
UPLOAD_ALLOWED_PHOTOS=jpg,jpeg,png,gif
# Extensions autorisées - Vidéos
UPLOAD_ALLOWED_VIDEOS=mp4,mov,avi
# Chemins absolus des uploads (dans container, hors document root public/)
# Servis via location ^~ /uploads/ { alias /var/www/html/uploads/; }
UPLOAD_PATH_PHOTOS=/var/www/html/uploads/incidents
UPLOAD_PATH_VIDEOS=/var/www/html/uploads/videos
# Permissions fichiers (format octal)
# 0755 = rwxr-xr-x (owner: RWX, group/others: RX)
# Conforme ANSSI (pas de 0777)
UPLOAD_PERMISSIONS=0755
# Floutage automatique des visages (RGPD)
# true = Activer face blurring après upload
# false = Désactiver (photos originales conservées)
FACE_BLURRING_ENABLED=true
⚠️ Cohérence Configuration :
Si vous changez UPLOAD_MAX_SIZE_MB, modifier aussi :
-
Dockerfile :
-
nginx.conf :
7. Email (SMTP)¶
# Serveur SMTP
# Exemples: smtp.gmail.com, smtp.office365.com, smtp.sendgrid.net
SMTP_HOST=smtp.example.com
# Port SMTP
# 25 = SMTP (non chiffré, obsolète)
# 587 = STARTTLS (recommandé)
# 465 = SMTPS (SSL)
SMTP_PORT=587
# Utilisateur SMTP
SMTP_USER=noreply@votre-domaine.fr
# Mot de passe SMTP
# ⚠️ Gmail: utiliser App Password, pas mot de passe compte
SMTP_PASSWORD=votre_mot_de_passe_email
# Adresse expéditeur (FROM)
SMTP_FROM=noreply@votre-domaine.fr
# Nom expéditeur
SMTP_FROM_NAME="Urbafix - Signalements"
Exemples Providers :
Gmail :
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=votre-email@gmail.com
SMTP_PASSWORD=app_password_16_caracteres
SendGrid :
Office 365 :
SMTP_HOST=smtp.office365.com
SMTP_PORT=587
SMTP_USER=votre-email@votreentreprise.com
SMTP_PASSWORD=votre_mot_de_passe
8. CORS¶
# Origines autorisées pour CORS (API publique)
# Séparer par virgules si plusieurs origines
# * = Toutes origines (dev seulement)
CORS_ALLOWED_ORIGINS=*
Production :
# Application mobile uniquement
CORS_ALLOWED_ORIGINS=https://app.urbafix.fr,https://admin.urbafix.fr
9. Fuseau Horaire¶
# Fuseau horaire PHP et MariaDB
# Format: Continent/Ville
# Liste: https://www.php.net/manual/en/timezones.php
TIMEZONE=Europe/Paris
Exemples :
- France métropolitaine : Europe/Paris
- Réunion : Indian/Reunion
- Guadeloupe/Martinique : America/Martinique
- Nouvelle-Calédonie : Pacific/Noumea
10. Sessions¶
# Driver de sessions
# file = Stockage fichiers PHP (default, single-instance)
# redis = Stockage Redis (multi-instances)
SESSION_DRIVER=file
# Nom du cookie de session
# ⚠️ Doit être unique si plusieurs apps sur même domaine
SESSION_NAME=URBAFIX_SESSION
# Configuration Redis (si SESSION_DRIVER=redis)
SESSION_REDIS_HOST=redis
SESSION_REDIS_PORT=6379
SESSION_REDIS_PASSWORD= # Hérité de REDIS_PASSWORD si vide
SESSION_REDIS_DB=0 # Base de données Redis (0-15)
Quand utiliser Redis : - ✅ Multi-instances web (load balancer) - ✅ Failover / haute disponibilité - ❌ Single instance (overhead inutile)
Migration file → redis :
# 1. Activer Redis
docker-compose --profile redis up -d
# 2. Modifier .env
SESSION_DRIVER=redis
SESSION_REDIS_PASSWORD=${REDIS_PASSWORD}
# 3. Redémarrer web
docker-compose restart web
# ⚠️ Sessions file existantes perdues (users déconnectés)
11. Cache¶
# Driver de cache
# null = Pas de cache (default, callback direct)
# redis = Cache centralisé
CACHE_DRIVER=null
# TTL (Time To Live) par type de données (secondes)
CACHE_TTL_TYPES=3600 # Types incidents (1h)
CACHE_TTL_MAIRIES=3600 # Mairies (1h)
CACHE_TTL_SERVICES=1800 # Services (30min)
CACHE_TTL_CONTACTS=3600 # Contacts (1h)
# Configuration Redis (si CACHE_DRIVER=redis)
CACHE_REDIS_HOST=redis
CACHE_REDIS_PORT=6379
CACHE_REDIS_PASSWORD= # Hérité de REDIS_PASSWORD si vide
CACHE_REDIS_DB=1 # DB séparée des sessions
Quand activer le cache : - ✅ Trafic > 100 requêtes/min - ✅ Réduire charge DB - ✅ Multi-instances (partage cache) - ❌ Données changeant très fréquemment
Métriques cache :
# Connexion Redis
docker-compose exec redis redis-cli -a ${REDIS_PASSWORD}
# Voir clés cache
redis> KEYS urbafix:cache:*
# Statistiques
redis> INFO stats
12. Stockage Fichiers¶
# Driver de stockage
# local = Filesystem local (default)
# s3 = AWS S3 / MinIO
STORAGE_DRIVER=local
# Configuration S3/MinIO (si STORAGE_DRIVER=s3)
STORAGE_S3_BUCKET=urbafix-prod-uploads
STORAGE_S3_REGION=eu-west-3 # Paris pour AWS
STORAGE_S3_KEY=AKIAIOSFODNN7EXAMPLE
STORAGE_S3_SECRET=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
STORAGE_S3_ENDPOINT= # Vide pour AWS S3, URL pour MinIO
Configuration AWS S3 :
STORAGE_DRIVER=s3
STORAGE_S3_BUCKET=urbafix-production
STORAGE_S3_REGION=eu-west-3
STORAGE_S3_KEY=AKIA...
STORAGE_S3_SECRET=...
STORAGE_S3_ENDPOINT=
Configuration MinIO (S3-compatible) :
STORAGE_DRIVER=s3
STORAGE_S3_BUCKET=uploads
STORAGE_S3_REGION=us-east-1
STORAGE_S3_KEY=minioadmin
STORAGE_S3_SECRET=minioadmin
STORAGE_S3_ENDPOINT=http://minio:9000
⚠️ Sécurité Production : - Utiliser IAM roles (EC2/ECS) au lieu de clés statiques - Ou Docker Secrets pour clés - Activer chiffrement S3 server-side (AES-256)
Migration local → S3 :
# 1. Créer bucket S3
aws s3 mb s3://urbafix-prod-uploads --region eu-west-3
# 2. Copier uploads existants
aws s3 sync ./public/backend/uploads/ s3://urbafix-prod-uploads/
# 3. Modifier .env
STORAGE_DRIVER=s3
STORAGE_S3_BUCKET=urbafix-prod-uploads
# 4. Redémarrer
docker-compose restart web
# 5. Supprimer volume uploads (optionnel)
# docker volume rm urbafix_uploads
13. Queue Asynchrone¶
# Driver de queue
# sync = Exécution immédiate (default, comportement actuel)
# redis = Queue Redis + workers
QUEUE_DRIVER=sync
# Configuration Redis (si QUEUE_DRIVER=redis)
QUEUE_REDIS_HOST=redis
QUEUE_REDIS_PORT=6379
QUEUE_REDIS_PASSWORD= # Hérité de REDIS_PASSWORD si vide
QUEUE_REDIS_DB=2 # DB séparée (sessions=0, cache=1, queue=2)
Jobs asynchrones :
- BlurFacesJob : Floutage visages RGPD
- CalculatePhashJob : Calcul pHash photos
- SendEmailNotificationJob : Emails notifications
Activation workers :
# 1. Activer Redis queue
QUEUE_DRIVER=redis
# 2. Créer bin/worker.php (voir DOCKER_STATELESS.md)
# 3. Lancer workers Supervisord
# /etc/supervisor/conf.d/urbafix-workers.conf
Monitoring queue :
# Taille queue
docker-compose exec redis redis-cli -a ${REDIS_PASSWORD} LLEN urbafix:queue:default
# Voir jobs en attente
docker-compose exec redis redis-cli -a ${REDIS_PASSWORD} LRANGE urbafix:queue:default 0 -1
14. Règles Métier¶
# Seuil de distance GPS pour validation (mètres)
# Utilisé pour: validation GPS vidéos vs incident
# Valeur recommandée: 100m (précision GPS mobile)
INCIDENT_GPS_THRESHOLD_METERS=100
# Distance de regroupement automatique (mètres)
# Incidents < distance avec même type = groupe
# Valeur recommandée: 10m
INCIDENT_GROUPING_DISTANCE_METERS=10
# Seuil de similitude pHash (bits différents)
# 0 = Images identiques
# 12 = Similaires (recommandé)
# 64 = Totalement différentes
INCIDENT_GROUPING_PHASH_THRESHOLD=12
# Limite export données (lignes)
# Protection contre exports massifs
# Valeur recommandée: 10000
EXPORT_MAX_ROWS=10000
Tuning Performance :
Regroupement agressif (moins de doublons) :
INCIDENT_GROUPING_DISTANCE_METERS=20 # 20m au lieu de 10m
INCIDENT_GROUPING_PHASH_THRESHOLD=15 # Plus tolérant
Regroupement strict (éviter faux positifs) :
Configurations par Environnement¶
Développement (.env.dev)¶
DB_HOST=db
DB_PASSWORD=dev_password_simple
APP_URL=http://localhost:8080
APP_ENV=dev
APP_DEBUG=true
WEB_PORT=8080
DB_EXTERNAL_PORT=3306
REDIS_PORT=6379
SESSION_DRIVER=file
CACHE_DRIVER=null
STORAGE_DRIVER=local
QUEUE_DRIVER=sync
CORS_ALLOWED_ORIGINS=*
Staging (.env.staging)¶
DB_HOST=db
DB_PASSWORD=staging_secure_password_32chars
APP_URL=https://staging.urbafix.fr
APP_ENV=staging
APP_DEBUG=false
WEB_PORT=8080
# DB_EXTERNAL_PORT commenté
# REDIS_PORT commenté
SESSION_DRIVER=redis
CACHE_DRIVER=redis
STORAGE_DRIVER=local
QUEUE_DRIVER=sync
REDIS_PASSWORD=staging_redis_password_32chars
CORS_ALLOWED_ORIGINS=https://staging.urbafix.fr
Production (.env.production)¶
DB_HOST=db
DB_PASSWORD=$(cat /run/secrets/db_password)
MYSQL_ROOT_PASSWORD=$(cat /run/secrets/db_root_password)
APP_URL=https://urbafix.fr
APP_ENV=production
APP_DEBUG=false
WEB_PORT=8080
SESSION_DRIVER=redis
CACHE_DRIVER=redis
STORAGE_DRIVER=s3
QUEUE_DRIVER=redis
REDIS_PASSWORD=$(cat /run/secrets/redis_password)
STORAGE_S3_BUCKET=urbafix-prod-uploads
STORAGE_S3_REGION=eu-west-3
STORAGE_S3_KEY=$(cat /run/secrets/aws_access_key)
STORAGE_S3_SECRET=$(cat /run/secrets/aws_secret_key)
CORS_ALLOWED_ORIGINS=https://urbafix.fr,https://app.urbafix.fr
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASSWORD=$(cat /run/secrets/sendgrid_api_key)
FACE_BLURRING_ENABLED=true
Docker Secrets :
# Créer secrets
echo "prod_db_password" | docker secret create db_password -
echo "prod_redis_password" | docker secret create redis_password -
# docker-compose.yml
secrets:
db_password:
external: true
redis_password:
external: true
services:
web:
secrets:
- db_password
- redis_password
Validation Configuration¶
Script de validation¶
Fichier : bin/validate_config.php
<?php
require_once __DIR__ . '/../src/Config.php';
$config = Config::getInstance();
$errors = [];
// Vérifier mots de passe
if (getenv('DB_PASSWORD') === 'changez_ce_mot_de_passe_2024') {
$errors[] = "DB_PASSWORD: Mot de passe par défaut détecté";
}
if (getenv('REDIS_PASSWORD') === 'changez_ce_mot_de_passe_redis') {
$errors[] = "REDIS_PASSWORD: Mot de passe par défaut détecté";
}
// Vérifier cohérence
if ($config->get('cache.driver') === 'redis' && !extension_loaded('redis')) {
$errors[] = "CACHE_DRIVER=redis mais extension Redis non chargée";
}
// Afficher résultats
if (empty($errors)) {
echo "✅ Configuration valide\n";
} else {
echo "❌ Erreurs détectées:\n";
foreach ($errors as $error) {
echo " - $error\n";
}
exit(1);
}
Utilisation :
Checklist Pré-Déploiement¶
Développement¶
- Copier
.env.example→.env - Modifier
DB_PASSWORD(optionnel) - Lancer
docker-compose up -d
Staging¶
- Changer
DB_PASSWORD(32+ caractères) - Changer
REDIS_PASSWORD(32+ caractères) -
APP_ENV=staging,APP_DEBUG=false - Activer Redis (
SESSION_DRIVER=redis,CACHE_DRIVER=redis) - Configurer SMTP (SendGrid/Mailgun)
Production¶
- Changer TOUS les mots de passe
- Utiliser Docker Secrets pour credentials
-
APP_ENV=production,APP_DEBUG=false - Commenter
DB_EXTERNAL_PORT,REDIS_PORT - Activer S3 (
STORAGE_DRIVER=s3) - Activer queue Redis (
QUEUE_DRIVER=redis) - Configurer CORS restrictif
- TLS 1.3 via reverse proxy
- Firewall UFW actif
- Backups automatiques (cron)
- Monitoring (Prometheus/Datadog)
- Logs centralisés (ELK/CloudWatch)
Ressources¶
- .env.example - Template configuration
- DOCKER_STATELESS.md - Configuration Docker
- DEPLOYMENT.md - Procédures déploiement
- ARCHITECTURE.md - Architecture technique