From ba1375805871e385aebe971c41fd99557e98c472 Mon Sep 17 00:00:00 2001 From: Gato Date: Sat, 4 Jul 2026 05:22:34 +0200 Subject: [PATCH] feat(luz): stacks dev + prod avec backend et BDD (routing /api Traefik) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute l'environnement de test luz-dev/ (webapp + backend /api + PostgreSQL, profil Spring dev avec seed) et complète le stack prod luz/ avec db + backend sur luz.goutailler-olivier.com/api. Images chargées en direct par SSH via Luz/script/deploy.sh (sans registre), d'où les tags localhost/luz-*. Co-Authored-By: Claude Opus 4.8 (1M context) --- luz-dev/.env.example | 14 ++++++ luz-dev/docker-compose.yml | 90 ++++++++++++++++++++++++++++++++++++++ luz/.env.example | 18 ++++++++ luz/docker-compose.yml | 71 +++++++++++++++++++++++++++--- 4 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 luz-dev/.env.example create mode 100644 luz-dev/docker-compose.yml create mode 100644 luz/.env.example diff --git a/luz-dev/.env.example b/luz-dev/.env.example new file mode 100644 index 0000000..28901c9 --- /dev/null +++ b/luz-dev/.env.example @@ -0,0 +1,14 @@ +# Secrets du stack de test Luz — copier en .env (git-ignoré) avant de démarrer. +# cp .env.example .env +# +# Note : le script Luz/script/deploy.sh génère automatiquement ce .env avec des +# valeurs fortes au premier déploiement. Ce fichier reste utile pour un démarrage +# manuel (docker compose up -d) directement sur le serveur. + +# Mot de passe PostgreSQL (partagé entre le container db et le backend). +# openssl rand -hex 16 +DB_PASSWORD=changeme + +# Secret de signature des JWT. NE JAMAIS réutiliser le défaut de application.yml. +# openssl rand -base64 32 +JWT_SECRET=changeme-use-a-long-random-string diff --git a/luz-dev/docker-compose.yml b/luz-dev/docker-compose.yml new file mode 100644 index 0000000..061f376 --- /dev/null +++ b/luz-dev/docker-compose.yml @@ -0,0 +1,90 @@ +# Stack de TEST Luz — luz-dev.goutailler-olivier.com +# +# Frontend : https://luz-dev.goutailler-olivier.com → webapp (nginx :80) +# Backend : https://luz-dev.goutailler-olivier.com/api → backend Spring (:8080) +# +# Déployé par le script Luz/script/deploy.sh (transfert direct des images en SSH, +# sans registre). Les images sont buildées en local puis chargées sur le serveur +# sous les tags « localhost/luz-*:dev » — d'où l'absence de champ « build » ici. +# +# Profil Spring « dev » : la base est réinitialisée (TRUNCATE + seed.sql) à chaque +# démarrage du backend. Données de test fixes, idéales pour l'app mobile. +# +# Prérequis serveur : Traefik v3 + réseau externe « proxy » (voir ../traefik/), +# et un enregistrement DNS A « luz-dev » pointant sur le serveur (Let's Encrypt HTTP-01). +name: luz-dev + +services: + db: + image: postgres:17 + container_name: luz-dev-db + restart: unless-stopped + environment: + POSTGRES_DB: luz + POSTGRES_USER: luz + POSTGRES_PASSWORD: ${DB_PASSWORD} + TZ: Europe/Paris + healthcheck: + test: ["CMD-SHELL", "pg_isready -U luz -d luz"] + interval: 10s + timeout: 5s + retries: 5 + volumes: + - luz_dev_db:/var/lib/postgresql/data + networks: + - luz-dev-net + + backend: + image: localhost/luz-backend:dev + container_name: luz-dev-backend + restart: unless-stopped + depends_on: + db: + condition: service_healthy + environment: + DB_HOST: db + DB_PORT: 5432 + DB_NAME: luz + DB_USER: luz + DB_PASSWORD: ${DB_PASSWORD} + JWT_SECRET: ${JWT_SECRET} + SPRING_PROFILES_ACTIVE: dev # TRUNCATE + rejeu de seed.sql à chaque démarrage + TZ: Europe/Paris + networks: + - luz-dev-net + - proxy + labels: + - traefik.enable=true + - traefik.http.routers.luz-dev-backend.rule=Host(`luz-dev.goutailler-olivier.com`) && PathPrefix(`/api`) + - traefik.http.routers.luz-dev-backend.entrypoints=websecure + - traefik.http.routers.luz-dev-backend.tls.certresolver=le + - traefik.http.services.luz-dev-backend.loadbalancer.server.port=8080 + - traefik.docker.network=proxy + + webapp: + image: localhost/luz-webapp:dev + container_name: luz-dev-webapp + restart: unless-stopped + depends_on: + - backend + environment: + TZ: Europe/Paris + networks: + - proxy + labels: + - traefik.enable=true + - traefik.http.routers.luz-dev-webapp.rule=Host(`luz-dev.goutailler-olivier.com`) + - traefik.http.routers.luz-dev-webapp.entrypoints=websecure + - traefik.http.routers.luz-dev-webapp.tls.certresolver=le + - traefik.http.services.luz-dev-webapp.loadbalancer.server.port=80 + - traefik.docker.network=proxy + +volumes: + luz_dev_db: + +networks: + luz-dev-net: + driver: bridge + proxy: + external: true + name: proxy diff --git a/luz/.env.example b/luz/.env.example new file mode 100644 index 0000000..2ebf10a --- /dev/null +++ b/luz/.env.example @@ -0,0 +1,18 @@ +# Secrets du stack de PRODUCTION Luz — copier en .env (git-ignoré) avant de démarrer. +# cp .env.example .env +# +# Note : le script Luz/script/deploy.sh prod génère automatiquement ce .env avec +# des valeurs fortes au premier déploiement. Ce fichier reste utile pour un +# démarrage manuel sur le serveur. + +# Mot de passe PostgreSQL (partagé entre le container db et le backend). +# openssl rand -hex 16 +DB_PASSWORD=changeme + +# Secret de signature des JWT. NE JAMAIS réutiliser le défaut de application.yml. +# openssl rand -base64 32 +JWT_SECRET=changeme-use-a-long-random-string + +# (Optionnel) Racine des données persistantes. La BDD vit dans ${DATA_PATH}/luz/db_data. +# Défaut : ~/Applications/data +#DATA_PATH=/home/gato/Applications/data diff --git a/luz/docker-compose.yml b/luz/docker-compose.yml index 7e339fa..2db73f0 100644 --- a/luz/docker-compose.yml +++ b/luz/docker-compose.yml @@ -1,17 +1,75 @@ +# Stack de PRODUCTION Luz — luz.goutailler-olivier.com +# +# Frontend : https://luz.goutailler-olivier.com → webapp (nginx :80) +# Backend : https://luz.goutailler-olivier.com/api → backend Spring (:8080) +# +# Déployé par le script Luz/script/deploy.sh prod (transfert direct des images en +# SSH, sans registre). Les images sont buildées en local puis chargées sur le +# serveur sous les tags « localhost/luz-*:latest » — d'où l'absence de « build ». +# +# PAS de profil « dev » : Flyway applique les migrations, la base est PERSISTANTE +# (bind sous ${DATA_PATH}/luz/db_data), les données ne sont jamais réinitialisées. +# +# Prérequis serveur : Traefik v3 + réseau externe « proxy » (voir ../traefik/), +# DNS A « luz » → serveur. name: luz services: - luz: - image: git.goutailler-olivier.com/gato/luz:latest + db: + image: postgres:17 + container_name: luz-db + restart: unless-stopped + environment: + POSTGRES_DB: luz + POSTGRES_USER: luz + POSTGRES_PASSWORD: ${DB_PASSWORD} + TZ: Europe/Paris + healthcheck: + test: ["CMD-SHELL", "pg_isready -U luz -d luz"] + interval: 10s + timeout: 5s + retries: 5 + volumes: + - ${DATA_PATH:-~/Applications/data}/luz/db_data:/var/lib/postgresql/data + networks: + - luz-net + + backend: + image: localhost/luz-backend:latest + container_name: luz-backend + restart: unless-stopped + depends_on: + db: + condition: service_healthy + environment: + DB_HOST: db + DB_PORT: 5432 + DB_NAME: luz + DB_USER: luz + DB_PASSWORD: ${DB_PASSWORD} + JWT_SECRET: ${JWT_SECRET} + TZ: Europe/Paris + networks: + - luz-net + - proxy + labels: + - traefik.enable=true + - traefik.http.routers.luz-backend.rule=Host(`luz.goutailler-olivier.com`) && PathPrefix(`/api`) + - traefik.http.routers.luz-backend.entrypoints=websecure + - traefik.http.routers.luz-backend.tls.certresolver=le + - traefik.http.services.luz-backend.loadbalancer.server.port=8080 + - traefik.docker.network=proxy + + webapp: + image: localhost/luz-webapp:latest container_name: luz restart: unless-stopped - + depends_on: + - backend environment: TZ: Europe/Paris - networks: - proxy - labels: - traefik.enable=true - traefik.http.routers.luz.rule=Host(`luz.goutailler-olivier.com`) @@ -19,9 +77,10 @@ services: - traefik.http.routers.luz.tls.certresolver=le - traefik.http.services.luz.loadbalancer.server.port=80 - traefik.docker.network=proxy - - com.centurylinklabs.watchtower.enable=true networks: + luz-net: + driver: bridge proxy: external: true name: proxy