fix(infra,ci): aligne le provisionnement et le déploiement sur Airflow 3
La migration Airflow 3 est arrivée sur `dev` après l'écriture du chemin de déploiement, qui en a gardé quatre traces fausses, invisibles en CI puisque aucun job ne joue ce chemin. `provision-host.sh` substituait `AIRFLOW_WEBSERVER_SECRET_KEY`, clé disparue. `AIRFLOW_API_SECRET_KEY` et `AIRFLOW_JWT_SECRET` restaient donc à `change_me` dans le `.env` posé sur la machine, et le `:?` d'`airflow-init` ne voit pas une valeur d'exemple : la stack aurait démarré avec un secret de session et un secret JWT prévisibles. Le `.env` est maintenant écrit après contrôle, et le script refuse de le poser s'il reste un `change_me` hors `APP_MOCK_API_*`. `make services-up` démarrait `airflow-webserver`, service supprimé par la migration ; seul `airflow-up` avait été aligné. L'overlay posait `AIRFLOW__WEBSERVER__WORKERS`, sans effet en Airflow 3 où la section est `[api]`. Le réglage disparaît plutôt que d'être renommé : le défaut y vaut un worker, moins que les deux qu'on visait. Le diagnostic d'échec de `deploy.yml` lisait les journaux sans l'overlay, donc sans service `proxy` : il échouait avant d'imprimer quoi que ce soit.
This commit is contained in:
+2
-2
@@ -70,7 +70,7 @@ PUBLIC_ORIGIN=
|
||||
PROXY_HTTP_PORT=
|
||||
PROXY_HTTPS_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, et le webserver Airflow lance 4 workers gunicorn.
|
||||
# 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
|
||||
AIRFLOW_WEBSERVER_WORKERS=2
|
||||
|
||||
@@ -52,6 +52,7 @@ jobs:
|
||||
done
|
||||
echo "L'API ne répond pas après 3 minutes" >&2
|
||||
cd "/srv/enervision/${ENVIRONNEMENT}"
|
||||
docker compose ps
|
||||
docker compose logs --tail=50 backend proxy
|
||||
compose="docker compose -f docker-compose.yml -f docker-compose.prod.yml"
|
||||
$compose ps
|
||||
$compose logs --tail=50 backend proxy
|
||||
exit 1
|
||||
|
||||
@@ -67,7 +67,7 @@ services-up: ## Démarre les services conteneurisés dont `make dev` dépend (ba
|
||||
docker compose up -d db mailpit
|
||||
@$(MAKE) --no-print-directory db-wait
|
||||
@$(MAKE) --no-print-directory db-ensure-airflow
|
||||
docker compose up -d airflow-init airflow-webserver airflow-scheduler
|
||||
docker compose up -d airflow-init airflow-apiserver airflow-scheduler airflow-dag-processor
|
||||
|
||||
dev-backend: ## Lance l'API seule en rechargement à chaud
|
||||
@echo "backend -> http://localhost:8000 (docs sur /docs)"
|
||||
|
||||
@@ -94,8 +94,9 @@ et frontend en rechargement a chaud sur le poste.
|
||||
| Mailpit | <http://localhost:8025> |
|
||||
|
||||
Le `.env` doit porter les cles Airflow avant le premier `make dev` : `AIRFLOW_FERNET_KEY`,
|
||||
`AIRFLOW_WEBSERVER_SECRET_KEY`, `AIRFLOW_APP_SECRET_KEY` et `AIRFLOW_ADMIN_PASSWORD`. Sans elles
|
||||
`airflow-init` refuse de demarrer, et `airflow-webserver` comme `airflow-scheduler` avec lui.
|
||||
`AIRFLOW_API_SECRET_KEY`, `AIRFLOW_JWT_SECRET`, `AIRFLOW_APP_SECRET_KEY` et
|
||||
`AIRFLOW_ADMIN_PASSWORD`. Sans elles `airflow-init` refuse de demarrer, et `airflow-apiserver`,
|
||||
`airflow-scheduler` et `airflow-dag-processor` avec lui.
|
||||
|
||||
Les cibles d'origine restent disponibles pour ne demarrer qu'une partie : `make db-up`,
|
||||
`make airflow-up`, `make dev-backend`, `make dev-frontend`.
|
||||
|
||||
@@ -25,8 +25,6 @@ services:
|
||||
airflow-apiserver:
|
||||
ports: !override
|
||||
- "127.0.0.1:${AIRFLOW_PORT:-8080}:8080"
|
||||
environment:
|
||||
AIRFLOW__WEBSERVER__WORKERS: ${AIRFLOW_WEBSERVER_WORKERS:-2}
|
||||
|
||||
backend:
|
||||
ports: !reset null
|
||||
|
||||
@@ -63,8 +63,9 @@ secret.
|
||||
|
||||
- Deux TimescaleDB sur une machine de 8 Go : sans réglage, chacune se réserverait 25 % de la
|
||||
RAM au premier démarrage. L'overlay fixe `TS_TUNE_MEMORY` à 2 Go et `TS_TUNE_NUM_CPUS` à 2 par
|
||||
base, et 2 workers gunicorn par webserver Airflow. La montée à 32 Go prévue par les
|
||||
consignes est à demander.
|
||||
base. Airflow 3 n'a rien à régler de ce côté : son api-server lance un seul worker par défaut,
|
||||
là où le webserver d'Airflow 2 en lançait quatre. La montée à 32 Go prévue par les consignes
|
||||
est à demander.
|
||||
- Un runner auto-hébergé sur un dépôt public exécute le code qu'on lui envoie. `deploy.yml` ne
|
||||
se déclenche jamais sur `pull_request`, le runner tourne sous un utilisateur dédié, et le
|
||||
dépôt doit exiger une approbation pour les workflows des PR externes.
|
||||
|
||||
@@ -47,13 +47,15 @@ preparer() {
|
||||
fi
|
||||
|
||||
if [[ ! -f "$dossier/.env" ]]; then
|
||||
local brouillon="$dossier/.env.brouillon" oubliees
|
||||
sed -e "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(secret)|" \
|
||||
-e "s|^POSTGRES_PORT=.*|POSTGRES_PORT=$port_pg|" \
|
||||
-e "s|^APP_SECRET_KEY=.*|APP_SECRET_KEY=$(secret)|" \
|
||||
-e "s|^MAILPIT_UI_PORT=.*|MAILPIT_UI_PORT=$port_mailpit|" \
|
||||
-e "s|^AIRFLOW_PORT=.*|AIRFLOW_PORT=$port_airflow|" \
|
||||
-e "s|^AIRFLOW_FERNET_KEY=.*|AIRFLOW_FERNET_KEY=$(fernet)|" \
|
||||
-e "s|^AIRFLOW_WEBSERVER_SECRET_KEY=.*|AIRFLOW_WEBSERVER_SECRET_KEY=$(secret)|" \
|
||||
-e "s|^AIRFLOW_API_SECRET_KEY=.*|AIRFLOW_API_SECRET_KEY=$(secret)|" \
|
||||
-e "s|^AIRFLOW_JWT_SECRET=.*|AIRFLOW_JWT_SECRET=$(secret)|" \
|
||||
-e "s|^AIRFLOW_ADMIN_PASSWORD=.*|AIRFLOW_ADMIN_PASSWORD=$(secret | cut -c1-20)|" \
|
||||
-e "s|^AIRFLOW_APP_SECRET_KEY=.*|AIRFLOW_APP_SECRET_KEY=$(secret)|" \
|
||||
-e "s|^PUBLIC_HOST=.*|PUBLIC_HOST=$hote|" \
|
||||
@@ -61,13 +63,21 @@ preparer() {
|
||||
-e "s|^COMPOSE_PROJECT_NAME=.*|COMPOSE_PROJECT_NAME=enervision-$env|" \
|
||||
-e "s|^PROXY_HTTP_PORT=.*|PROXY_HTTP_PORT=$port_http|" \
|
||||
-e "s|^PROXY_HTTPS_PORT=.*|PROXY_HTTPS_PORT=$port_https|" \
|
||||
"$dossier/.env.example" > "$dossier/.env"
|
||||
"$dossier/.env.example" > "$brouillon"
|
||||
# Branche antérieure à l'ADR 0009 : ces clés manquent alors dans .env.example.
|
||||
for cle in "COMPOSE_PROJECT_NAME=enervision-$env" "PUBLIC_ORIGIN=$origine" \
|
||||
"PROXY_HTTP_PORT=$port_http" "PROXY_HTTPS_PORT=$port_https"; do
|
||||
grep -q "^${cle%%=*}=" "$dossier/.env" || echo "$cle" >> "$dossier/.env"
|
||||
grep -q "^${cle%%=*}=" "$brouillon" || echo "$cle" >> "$brouillon"
|
||||
done
|
||||
chmod 600 "$dossier/.env"
|
||||
# Piège : une clé renommée en amont garde sa valeur d'exemple, que le `:?` du compose ne
|
||||
# voit pas puisqu'elle n'est pas vide. Cas vécu : AIRFLOW_WEBSERVER_SECRET_KEY, Airflow 3.
|
||||
oubliees="$(grep '=change_me$' "$brouillon" | grep -v '^APP_MOCK_API_' | cut -d= -f1 | tr '\n' ' ' || true)"
|
||||
if [[ -n "$oubliees" ]]; then
|
||||
rm -f "$brouillon"
|
||||
erreur "$env : secrets non générés, .env non écrit : $oubliees"
|
||||
fi
|
||||
chmod 600 "$brouillon"
|
||||
mv "$brouillon" "$dossier/.env"
|
||||
echo "$env : .env généré. Reste à renseigner APP_MOCK_API_USERNAME et APP_MOCK_API_PASSWORD."
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user