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:
@@ -69,6 +69,9 @@
|
|||||||
},
|
},
|
||||||
"serve": {
|
"serve": {
|
||||||
"builder": "@angular/build:dev-server",
|
"builder": "@angular/build:dev-server",
|
||||||
|
"options": {
|
||||||
|
"proxyConfig": "proxy.conf.js"
|
||||||
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
"buildTarget": "schotziad-km-tracker:build:production"
|
"buildTarget": "schotziad-km-tracker:build:production"
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// Proxy de développement pour `ng serve` : les appels du front vers `/api` sont
|
||||||
|
// relayés vers le backend. Le port du backend n'est PLUS codé en dur dans le
|
||||||
|
// front : il est lu depuis la variable d'environnement BACKEND_PORT (défaut 8080),
|
||||||
|
// ce qui permet à run-dev.sh de piloter un seul port côté backend ET côté proxy.
|
||||||
|
//
|
||||||
|
// En production, c'est nginx qui proxifie /api (ce fichier ne sert qu'en dev).
|
||||||
|
|
||||||
|
const backendPort = process.env.BACKEND_PORT || '8080';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
'/api': {
|
||||||
|
target: `http://localhost:${backendPort}`,
|
||||||
|
secure: false,
|
||||||
|
changeOrigin: true
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -17,8 +17,8 @@ import {
|
|||||||
/**
|
/**
|
||||||
* Service HTTP des trajets, résumés, exports PDF et navigation temporelle.
|
* Service HTTP des trajets, résumés, exports PDF et navigation temporelle.
|
||||||
*
|
*
|
||||||
* Toutes les routes sont relatives à `environment.apiUrl` (`/api` en prod,
|
* Toutes les routes sont relatives à `environment.apiUrl` (`/api`, en dev comme
|
||||||
* `http://localhost:8080/api` en dev). Les appels sont soumis au
|
* en prod ; en dev, le proxy `ng serve` relaie `/api` vers le backend). Les appels sont soumis au
|
||||||
* `timeoutInterceptor` (10 s, Exigence 1.9).
|
* `timeoutInterceptor` (10 s, Exigence 1.9).
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
// Environnement de développement.
|
// Environnement de développement.
|
||||||
// En dev, le frontend Angular tourne sur son propre serveur (ng serve, port 4200)
|
// En dev, le frontend Angular tourne sur son propre serveur (ng serve, port 4200).
|
||||||
// et adresse directement le backend ASP.NET Core.
|
// Les appels à `/api` sont relayés vers le backend par le proxy de dev (proxy.conf.js,
|
||||||
|
// cible `serve` dans angular.json), dont le port est paramétrable via BACKEND_PORT.
|
||||||
|
// L'API est donc consommée en same-origin via le chemin relatif `/api`, comme en prod :
|
||||||
|
// le port du backend n'est plus codé en dur dans le front.
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
// URL de base de l'API backend en développement.
|
// Chemin relatif : le proxy de dev (proxy.conf.js) relaie /api vers le backend.
|
||||||
// Le backend écoute par défaut sur http://localhost:8080 (cf. Docker / Program.cs).
|
apiUrl: '/api',
|
||||||
apiUrl: 'http://localhost:8080/api',
|
|
||||||
// Timeout HTTP appliqué par le TimeoutInterceptor (Exigence 1.9 : 10 secondes).
|
// Timeout HTTP appliqué par le TimeoutInterceptor (Exigence 1.9 : 10 secondes).
|
||||||
httpTimeoutMs: 10000,
|
httpTimeoutMs: 10000,
|
||||||
// API Base Adresse Nationale (autocomplétion adresses françaises).
|
// API Base Adresse Nationale (autocomplétion adresses françaises).
|
||||||
|
|||||||
+35
-9
@@ -1,13 +1,33 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Lance en mode développement le backend (port 8080) et le frontend Angular (port 4200)
|
# Lance en mode développement le backend (port BACKEND_PORT, défaut 8080) et le
|
||||||
# avec la base SQLite réelle. À utiliser hors Docker, pour le développement local.
|
# frontend Angular (ng serve, port 4200) avec la base SQLite réelle.
|
||||||
|
# À utiliser hors Docker, pour le développement local.
|
||||||
#
|
#
|
||||||
# Usage : ./run-dev.sh
|
# 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
|
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)"
|
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) -------------------------------------------------------
|
# --- Backend (.NET 8) -------------------------------------------------------
|
||||||
export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH"
|
export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH"
|
||||||
export DOTNET_ROOT="$HOME/.dotnet"
|
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= »
|
# sortie du backend (repli LoggingEmailService). Cherche « reset-password?token= »
|
||||||
# dans les logs pour tester la réinitialisation sans email réel.
|
# 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)"
|
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:8080 &
|
dotnet run --project "$RACINE/backend/SchotzIadKmTracker.Api" --urls "http://localhost:$BACKEND_PORT" &
|
||||||
PID_BACK=$!
|
PID_BACK=$!
|
||||||
|
|
||||||
# --- Frontend (Angular via nvm/Node 22) -------------------------------------
|
# --- Frontend (Angular via nvm/Node 22) -------------------------------------
|
||||||
@@ -78,14 +98,20 @@ nvm use 22 >/dev/null
|
|||||||
echo "→ Nettoyage du cache Angular (.angular/cache)"
|
echo "→ Nettoyage du cache Angular (.angular/cache)"
|
||||||
rm -rf "$RACINE/frontend/.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 ) &
|
( cd "$RACINE/frontend" && npm start ) &
|
||||||
PID_FRONT=$!
|
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() {
|
cleanup() {
|
||||||
echo ""
|
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
|
kill "$PID_BACK" "$PID_FRONT" 2>/dev/null || true
|
||||||
pkill -f "SchotzIadKmTracker.Api" 2>/dev/null || true
|
pkill -f "SchotzIadKmTracker.Api" 2>/dev/null || true
|
||||||
}
|
}
|
||||||
@@ -127,7 +153,7 @@ if attendre_frontend; then
|
|||||||
echo ""
|
echo ""
|
||||||
echo "======================================================================"
|
echo "======================================================================"
|
||||||
echo " Application prête."
|
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 " Frontend : http://localhost:4200 ← ouvre cette URL maintenant"
|
||||||
echo ""
|
echo ""
|
||||||
echo " Au premier chargement, fais Ctrl+Shift+R pour vider le cache navigateur."
|
echo " Au premier chargement, fais Ctrl+Shift+R pour vider le cache navigateur."
|
||||||
|
|||||||
Reference in New Issue
Block a user