# Variables lues par docker-compose.yml à la racine. # Le backend lancé hors conteneur (`make dev`) lit apps/backend/.env, pas ce fichier. POSTGRES_USER=enervision POSTGRES_PASSWORD=change_me POSTGRES_DB=enervision # 5432 est souvent déjà pris par une autre base du poste. POSTGRES_PORT=5433 # `basic` renvoie des statistiques d'usage à Timescale. TIMESCALEDB_TELEMETRY=off APP_ENV=local APP_DEBUG=false APP_LOG_LEVEL=INFO # L'API refuse de démarrer tant que cette valeur reste un exemple ou fait moins de # 32 caractères. Générer la vôtre : python -c "import secrets; print(secrets.token_urlsafe(48))" APP_SECRET_KEY=change_me APP_CORS_ORIGINS=http://localhost:4200 BACKEND_PORT=8000 FRONTEND_PORT=3000 # Mailpit capture les courriels du backend, rien ne sort vers l'extérieur. MAILPIT_SMTP_PORT=1025 MAILPIT_UI_PORT=8025 # API Mock EnerVision APP_MOCK_API_BASE_URL=https://api-mock.charlieandre.fr APP_MOCK_API_USERNAME=change_me APP_MOCK_API_PASSWORD=change_me APP_MOCK_API_TIMEOUT_SECONDS=10 # Airflow (api-server + scheduler + dag-processor, LocalExecutor). Base de métadonnées dédiée `airflow` dans le # même conteneur `db` (cf. db/init/120-airflow-database.sql), pas un conteneur de plus. AIRFLOW_PORT=8080 # Chiffre les connexions/variables stockées par Airflow. Générer la vôtre : # python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" AIRFLOW_FERNET_KEY=change_me # Clé de session de l'api-server Airflow, distincte de la précédente. Générer la # vôtre : python -c "import secrets; print(secrets.token_urlsafe(48))" AIRFLOW_API_SECRET_KEY=change_me # Secret des jetons JWT entre scheduler, tâches et api-server (conteneurs distincts, le secret # doit être partagé). Même générateur que ci-dessus. AIRFLOW_JWT_SECRET=change_me AIRFLOW_ADMIN_USERNAME=admin # Compte Airflow créé au premier démarrage (service `airflow-init`), sans rapport avec les # comptes `app_user` d'EnerVision. AIRFLOW_ADMIN_PASSWORD=change_me AIRFLOW_ADMIN_EMAIL=admin@enervision.fr # `APP_SECRET_KEY` du backend, que le DAG `alertes` lance en sous-processus. Distincte de # celle de l'API : la détection ne signe aucun jeton, et Airflow exécute du code depuis son # interface (cf. ADR 0008). Générer la vôtre : # python -c "import secrets; print(secrets.token_urlsafe(48))" AIRFLOW_APP_SECRET_KEY=change_me # Garage, stockage objet S3 par environnement (ADR 0019) : un conteneur par projet Compose, publié # sur 127.0.0.1 seulement. Les six secrets ci-dessous sont exigés par `make services-up` et # `make stack-up` ; scripts/provision-host.sh les génère sur la VM. # 32 octets en hexadécimal, rien d'autre n'est accepté : openssl rand -hex 32 GARAGE_RPC_SECRET=change_me # Jetons de l'API d'administration et de /metrics (port 3903). Même générateur qu'APP_SECRET_KEY. GARAGE_ADMIN_TOKEN=change_me GARAGE_METRICS_TOKEN=change_me # Clé S3 créée au premier démarrage (`--default-bucket`). Identifiant : echo "GK$(openssl rand -hex 12)" # Secret : openssl rand -hex 32. Ne plus le changer ensuite, Garage refuserait de démarrer. GARAGE_ACCESS_KEY=change_me GARAGE_SECRET_KEY=change_me GARAGE_BUCKET=enervision-archives # Ports S3 et admin sur 127.0.0.1. Recette : 3910 et 3913, dev : 3920 et 3923. GARAGE_S3_PORT=3900 GARAGE_ADMIN_PORT=3903 # Rétention des mesures (ADR 0019, 0020) : le DAG `retention` exporte chaque nuit vers Garage les # chunks de `reading` plus vieux que cette borne, puis les supprime. L'historique de démonstration # s'arrête fin 2024 : sous 21 mois, la démo disparaîtrait. READING_RETENTION_DAYS=1095 # Clé SSE-C des archives, 32 octets en base64 : openssl rand -base64 32. La perdre rend les # archives illisibles ; la sauvegarder hors de la VM. GARAGE_SSE_KEY=change_me # Stack complète derrière le reverse proxy (docker-compose.prod.yml). # PUBLIC_HOST alimente l'origine CORS, le lien de réinitialisation et le certificat. PUBLIC_HOST=enervision.local ACME_EMAIL= # Trois environnements sur la même machine (ADR 0009, 0017) : un dossier, un `.env` et un projet # Compose chacun. Le nom de projet préfixe volumes, réseau et conteneurs et l'emporte sur `name:`. # Vide sur un poste de développement : le projet reste `enervision`. COMPOSE_PROJECT_NAME= # Origine publique, avec le port si le proxy HTTPS n'écoute pas 443. Vide : https://PUBLIC_HOST. # Sur la VM, provision-host.sh pose https://, sans port (frontal SNI). PUBLIC_ORIGIN= # Ports publiés par le proxy. Vides : 80 et 443. Sur la VM, provision-host.sh les pose sur 127.0.0.1, # derrière le frontal SNI, et décale aussi base, Mailpit et Airflow par environnement. PROXY_HTTP_PORT= PROXY_HTTPS_PORT= # Écouteur PROXY protocol du proxy, que seul le frontal de la VM joint (infra/front, ADR 0018). # Vide : port aléatoire sur 127.0.0.1. VM : 127.0.0.1:10444 en prod, 8444 en recette, 9444 en dev. PROXY_FRONT_PORT= # Réglages mémoire de la stack déployée. Sans eux, timescaledb-tune réserve 25 % de la RAM de la # machine à chaque base au premier démarrage. L'api-server Airflow 3 n'a rien à régler ici : son # nombre de workers vaut 1 par défaut, contre 4 pour le webserver d'Airflow 2. TS_TUNE_MEMORY=2GB TS_TUNE_NUM_CPUS=2 # Supervision (ADR 0016) : `monitoring` la démarre avec `make stack-up`, réglage de la prod. # Vide ailleurs, où `make monitoring-up` la lance à la demande. COMPOSE_PROFILES= # Jeton présenté par Prometheus sur `/metrics`, exigé par l'API dès qu'il est posé. Requis dès # que la supervision tourne ; même générateur que APP_SECRET_KEY. APP_METRICS_TOKEN=change_me # Compte `admin` de Grafana. Sans lui, le conteneur refuse de démarrer. GRAFANA_ADMIN_PASSWORD=change_me # Rôle PostgreSQL `supervision`, en lecture seule, de Grafana et de postgres-exporter # (db/roles/supervision.sql, posé par `make db-ensure-supervision`). SUPERVISION_DB_PASSWORD=change_me # Interfaces publiées sur 127.0.0.1 seulement, par tunnel SSH. 3000 est pris par le frontend. GRAFANA_PORT=3001 PROMETHEUS_PORT=9090 ALERTMANAGER_PORT=9093