Aller au contenu

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 :

openssl rand -base64 32

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 :

openssl rand -hex 64


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 :

  1. Dockerfile :

    RUN echo "upload_max_filesize = 64M" > /usr/local/etc/php/conf.d/uploads.ini \
     && echo "post_max_size = 64M" >> /usr/local/etc/php/conf.d/uploads.ini
    

  2. nginx.conf :

    client_max_body_size 64M;
    


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 :

SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASSWORD=SG.xxxxxxxxxxxxxxxxxxxx

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) :

INCIDENT_GROUPING_DISTANCE_METERS=5   # 5m
INCIDENT_GROUPING_PHASH_THRESHOLD=8   # Très similaire


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 :

php bin/validate_config.php


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