Dev : proxy /api paramétrable et arrêt propre du groupe de process

- run-dev.sh s'exécute dans sa propre session (setsid) et tue le GROUPE
  de process entier au cleanup : le backend (Kestrel) et ses enfants
  sont bien arrêtés, le port backend est réellement libéré à l'arrêt
- Port backend paramétrable via BACKEND_PORT (défaut 8080), transmis à
  la fois au backend (dotnet --urls) et au proxy de dev du front
- Nouveau frontend/proxy.conf.js : ng serve relaie /api vers
  http://localhost:${BACKEND_PORT} ; référencé dans angular.json (serve)
- environment.ts (dev) : apiUrl passe à '/api' (same-origin via proxy),
  le port du backend n'est plus codé en dur dans le front
- Prod inchangée (environment.prod.ts déjà en '/api', nginx)
This commit is contained in:
2026-10-13 08:30:25 +02:00
parent 6fb311a422
commit 0e5b1c4d0d
5 changed files with 63 additions and 16 deletions
+35 -9
View File
@@ -1,13 +1,33 @@
#!/usr/bin/env bash
# Lance en mode développement le backend (port 8080) et le frontend Angular (port 4200)
# avec la base SQLite réelle. À utiliser hors Docker, pour le développement local.
# Lance en mode développement le backend (port BACKEND_PORT, défaut 8080) et le
# frontend Angular (ng serve, port 4200) avec la base SQLite réelle.
# À utiliser hors Docker, pour le développement local.
#
# Usage : ./run-dev.sh
# Arrêt : Ctrl+C (les deux processus sont arrêtés ensemble).
# Arrêt : Ctrl+C (backend ET frontend sont arrêtés ensemble, port backend libéré).
#
# Le port du backend est paramétrable via BACKEND_PORT (ex. BACKEND_PORT=5080 ./run-dev.sh).
# Ce même port est transmis au backend (dotnet --urls) ET au proxy de dev du front
# (proxy.conf.js lit BACKEND_PORT), de sorte qu'il n'est défini qu'à un seul endroit.
set -uo pipefail
# --- Groupe de process dédié ------------------------------------------------
# Problème résolu : à l'arrêt, « dotnet run » / « npm start » lancent des process
# ENFANTS (le vrai serveur Kestrel, esbuild…) qui survivaient à un simple kill du
# PID parent, laissant le port backend occupé. Solution : exécuter tout le script
# dans sa PROPRE session/groupe de process (via setsid), puis tuer le GROUPE ENTIER
# au cleanup. On se relance une seule fois sous setsid si ce n'est pas déjà le cas.
if [[ -z "${RUN_DEV_SETSID:-}" ]] && command -v setsid >/dev/null 2>&1; then
export RUN_DEV_SETSID=1
exec setsid "$0" "$@"
fi
RACINE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Port du backend (paramétrable). Transmis au backend et au proxy de dev du front.
export BACKEND_PORT="${BACKEND_PORT:-8080}"
# --- Backend (.NET 8) -------------------------------------------------------
export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH"
export DOTNET_ROOT="$HOME/.dotnet"
@@ -61,8 +81,8 @@ export Auth__FrontendBaseUrl="${Auth__FrontendBaseUrl:-http://localhost:4200}"
# sortie du backend (repli LoggingEmailService). Cherche « reset-password?token= »
# dans les logs pour tester la réinitialisation sans email réel.
echo "→ Démarrage du backend sur http://localhost:8080 (base : $RACINE/backend/SchotzIadKmTracker.Api/trajets.db)"
dotnet run --project "$RACINE/backend/SchotzIadKmTracker.Api" --urls http://localhost:8080 &
echo "→ Démarrage du backend sur http://localhost:$BACKEND_PORT (base : $RACINE/backend/SchotzIadKmTracker.Api/trajets.db)"
dotnet run --project "$RACINE/backend/SchotzIadKmTracker.Api" --urls "http://localhost:$BACKEND_PORT" &
PID_BACK=$!
# --- Frontend (Angular via nvm/Node 22) -------------------------------------
@@ -78,14 +98,20 @@ nvm use 22 >/dev/null
echo "→ Nettoyage du cache Angular (.angular/cache)"
rm -rf "$RACINE/frontend/.angular/cache"
echo "→ Démarrage du frontend sur http://localhost:4200 (première compilation : patiente…)"
echo "→ Démarrage du frontend sur http://localhost:4200 (proxy /api → :$BACKEND_PORT ; première compilation : patiente…)"
( cd "$RACINE/frontend" && npm start ) &
PID_FRONT=$!
# --- Arrêt propre des deux processus ----------------------------------------
# --- Arrêt propre : on tue TOUT le groupe de process ------------------------
# Comme le script tourne dans sa propre session (setsid), son PID est aussi le PGID.
# `kill -- -$$` envoie le signal à TOUT le groupe (backend, frontend et leurs enfants),
# ce qui libère réellement le port backend. Repli ciblé par sécurité.
cleanup() {
echo ""
echo "→ Arrêt…"
echo "→ Arrêt (groupe de process)…"
# Signal au groupe entier (le '-' devant le PID = groupe). $$ = PID du script = PGID.
kill -TERM -- "-$$" 2>/dev/null || true
# Repli : au cas où certains process ne seraient pas dans le groupe.
kill "$PID_BACK" "$PID_FRONT" 2>/dev/null || true
pkill -f "SchotzIadKmTracker.Api" 2>/dev/null || true
}
@@ -127,7 +153,7 @@ if attendre_frontend; then
echo ""
echo "======================================================================"
echo " Application prête."
echo " Backend : http://localhost:8080/api"
echo " Backend : http://localhost:$BACKEND_PORT/api"
echo " Frontend : http://localhost:4200 ← ouvre cette URL maintenant"
echo ""
echo " Au premier chargement, fais Ctrl+Shift+R pour vider le cache navigateur."