Files
ENI-projet-piscine/.env.example
Johan LEROY 3e871a3e8b feat(deploy): URL sans port et certificats Let's Encrypt sur la VM ENI
Les trois environnements passent sur enervision-g3.duckdns.org, rec. et
dev. : noms publics qui visent l'IP privée de la VM, donc résolus sans
/etc/hosts sur le réseau de l'école et injoignables ailleurs (ADR 0018).

- infra/front : nginx sur le réseau de l'hôte, seul exposé en 80 et 443.
  Aiguille par SNI vers la stack visée sans déchiffrer le TLS, et lui
  transmet l'IP du client en PROXY protocol.
- Proxy de stack : écouteur 4443 en PROXY protocol, real_ip_header ;
  sans lui, limit_req et get_client_ip() compteraient tous les postes
  comme un seul. PROXY_FRONT_PORT le publie sur 127.0.0.1.
- make tls-duckdns : Let's Encrypt par défi DNS-01 via l'API DuckDNS
  (acme.sh 3.1.6), rejouable, rejoué à chaque déploiement et chaque nuit.
- provision-host.sh fait foi pour l'adressage et les secrets : un .env
  existant garde ses secrets, reçoit ceux qui manquent (supervision) et
  voit hôte et ports réalignés. Planifie le renouvellement des certificats.
- deploy.yml : nouvelles URL, sonde prod sur 10443, front-up en prod.
- Terraform : variable domaine. CI : validation du frontal.
2026-09-23 11:21:12 +02:00

96 lines
4.6 KiB
Bash

# 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
# 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=
# Deux environnements sur la même machine (ADR 0009) : 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.
# Recette : PUBLIC_HOST=rec.enervision.local et PUBLIC_ORIGIN=https://rec.enervision.local:8443.
PUBLIC_ORIGIN=
# Ports publiés par le proxy. Vides : 80 et 443. Recette : PROXY_HTTPS_PORT=8443 et
# PROXY_HTTP_PORT=127.0.0.1:8081, la redirection vers 443 n'ayant pas à être joignable de
# l'extérieur. Décaler aussi POSTGRES_PORT, MAILPIT_UI_PORT et AIRFLOW_PORT (5434, 8026, 8082).
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