Files
ENI-projet-piscine/docker-compose.prod.yml
T
Johan LEROY cb23895026 feat(infra,ci): deux environnements rec et prod sur la VM ENI, déployés par un runner auto-hébergé
Un projet Compose par environnement sur la même machine : ports du proxy et origine
publique en variables dans docker-compose.prod.yml, réglage mémoire des deux bases
TimescaleDB et du webserver Airflow. Le workflow deploy.yml déploie dev en recette et
main en production depuis un runner installé sur la VM, jamais sur pull_request.
scripts/provision-host.sh prépare les deux dossiers, secrets et certificats compris,
sans rien démarrer.

L'image frontend quitte dhi.io/nginx, registre authentifié dont personne n'a l'accès,
pour nginx:1.28-alpine : elle n'avait jamais été construite.

ADR 0009, vues infra et CI/CD, README et .env.example mis à jour.

Refs #21, #22
2026-09-21 14:59:32 +02:00

82 lines
2.6 KiB
YAML

# Piège : `APP_ENV` et `APP_DEBUG` sont en dur et non en `${APP_ENV:-prod}` : le `.env` du poste
# vaut `local` et reprendrait le dessus, ce qui laisserait le cookie sans `__Secure-` et
# rouvrirait `/docs`. Hors `local`, l'API exige en retour une origine CORS non vide.
# Piège : les listes de ports se cumulent à la fusion des deux fichiers. `!reset` est le seul
# moyen de dépublier 8000 et 3000 : sans lui, l'API resterait joignable en clair à côté du proxy.
# Piège : pas de `:?` sur `PUBLIC_HOST`. Compose interpole tout le fichier, y compris pour
# `stop` et `logs` : la garde vit dans `make stack-up`, qui la compare au certificat servi.
# Pourquoi : ports du proxy et origine publique en variables, pour que deux environnements
# cohabitent sur la même machine, chacun dans son projet Compose (ADR 0009).
name: enervision
services:
db:
ports: !override
- "127.0.0.1:${POSTGRES_PORT:-5433}:5432"
environment:
TS_TUNE_MEMORY: ${TS_TUNE_MEMORY:-2GB}
TS_TUNE_NUM_CPUS: ${TS_TUNE_NUM_CPUS:-2}
mailpit:
ports: !override
- "127.0.0.1:${MAILPIT_UI_PORT:-8025}:8025"
airflow-webserver:
ports: !override
- "127.0.0.1:${AIRFLOW_PORT:-8080}:8080"
environment:
AIRFLOW__WEBSERVER__WORKERS: ${AIRFLOW_WEBSERVER_WORKERS:-2}
backend:
ports: !reset null
command:
- uvicorn
- app.main:create_app
- --factory
- --host
- 0.0.0.0
- --port
- "8000"
- --proxy-headers
- --forwarded-allow-ips=*
environment:
APP_ENV: prod
APP_DEBUG: "false"
APP_TRUST_PROXY_HEADERS: "true"
APP_CORS_ORIGINS: ${PUBLIC_ORIGIN:-https://${PUBLIC_HOST:-enervision.local}}
APP_FRONTEND_RESET_PASSWORD_URL: ${PUBLIC_ORIGIN:-https://${PUBLIC_HOST:-enervision.local}}/reset-password
frontend:
ports: !reset null
proxy:
image: nginx:1.28-alpine
depends_on:
backend:
condition: service_healthy
frontend:
condition: service_started
ports:
- "${PROXY_HTTP_PORT:-80}:80"
- "${PROXY_HTTPS_PORT:-443}:443"
volumes:
- ./infra/proxy/nginx.conf:/etc/nginx/nginx.conf:ro
- ./infra/proxy/conf.d:/etc/nginx/conf.d:ro
- ./infra/proxy/tls:/etc/nginx/tls:ro
- acme_webroot:/var/www/certbot
restart: unless-stopped
certbot:
image: certbot/certbot:v5.8.0
profiles: ["acme"]
volumes:
- letsencrypt:/etc/letsencrypt
- acme_webroot:/var/www/certbot
- ./infra/proxy/tls:/tls
- ./infra/proxy/acme-deploy-hook.sh:/deploy-hook.sh:ro
volumes:
acme_webroot:
letsencrypt: