Compare commits
25 Commits
85350cfe86
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ae0d9f87f | |||
| 30887c066b | |||
| 23ce5c86e1 | |||
| 5558c206a0 | |||
| 9a37ed4b8f | |||
| 2b2a924916 | |||
| 44173a540b | |||
| 8efa725753 | |||
| d90b7bc34b | |||
| 7d3c6f164e | |||
| 7ed2d0b238 | |||
| ba13758058 | |||
| 42d006ee6e | |||
| bba8216cea | |||
| e19aeadc63 | |||
| cdefbe3a81 | |||
| f65ffea670 | |||
| 2e45a8cc10 | |||
| 5798440a9b | |||
| 0352ffd641 | |||
| 3ef9311729 | |||
| 9a477e8b7f | |||
| c65ffaa15a | |||
| 7f6d6a7aaf | |||
| bca776f118 |
@@ -1,2 +1,3 @@
|
|||||||
traefik-letsencrypt/
|
traefik-letsencrypt/
|
||||||
.env
|
.env
|
||||||
|
**/.env
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
name: bonsai-api-stack
|
|
||||||
|
|
||||||
services:
|
|
||||||
db:
|
|
||||||
image: postgres:16-alpine
|
|
||||||
container_name: bonsai-api-db
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: bonsai
|
|
||||||
POSTGRES_USER: bonsai
|
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
TZ: Europe/Paris
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U bonsai -d bonsai"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
volumes:
|
|
||||||
- ~/Applications/data/bonsai-api/db_data:/var/lib/postgresql/data
|
|
||||||
networks:
|
|
||||||
- bonsai-api-net
|
|
||||||
|
|
||||||
api:
|
|
||||||
image: git.goutailler-olivier.com/bonsai/bonsai-api:latest
|
|
||||||
container_name: bonsai-api
|
|
||||||
restart: unless-stopped
|
|
||||||
depends_on:
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
environment:
|
|
||||||
DATASOURCE_URL: jdbc:postgresql://db:5432/bonsai
|
|
||||||
DATASOURCE_USERNAME: bonsai
|
|
||||||
DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
KEYCLOAK_JWKS_URI: https://auth.goutailler-olivier.com/realms/bonsai/protocol/openid-connect/certs
|
|
||||||
CORS_ALLOWED_ORIGIN_PROD: https://bonsai.goutailler-olivier.com
|
|
||||||
TZ: Europe/Paris
|
|
||||||
networks:
|
|
||||||
- bonsai-api-net
|
|
||||||
- proxy
|
|
||||||
labels:
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.bonsai-api.rule=Host(`bonsai.goutailler-olivier.com`) && PathPrefix(`/api`)
|
|
||||||
- traefik.http.routers.bonsai-api.entrypoints=websecure
|
|
||||||
- traefik.http.routers.bonsai-api.tls.certresolver=le
|
|
||||||
- traefik.http.services.bonsai-api.loadbalancer.server.port=8080
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- com.centurylinklabs.watchtower.enable=true
|
|
||||||
|
|
||||||
networks:
|
|
||||||
bonsai-api-net:
|
|
||||||
driver: bridge
|
|
||||||
proxy:
|
|
||||||
external: true
|
|
||||||
name: proxy
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
name: bonsai-webapp
|
|
||||||
|
|
||||||
services:
|
|
||||||
bonsai-webapp:
|
|
||||||
image: git.goutailler-olivier.com/bonsai/bonsai-webapp:latest
|
|
||||||
container_name: bonsai-webapp
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
environment:
|
|
||||||
TZ: Europe/Paris
|
|
||||||
|
|
||||||
networks:
|
|
||||||
- proxy
|
|
||||||
|
|
||||||
labels:
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.bonsai-webapp.rule=Host(`bonsai.goutailler-olivier.com`)
|
|
||||||
- traefik.http.routers.bonsai-webapp.entrypoints=websecure
|
|
||||||
- traefik.http.routers.bonsai-webapp.tls.certresolver=le
|
|
||||||
- traefik.http.services.bonsai-webapp.loadbalancer.server.port=80
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- com.centurylinklabs.watchtower.enable=true
|
|
||||||
|
|
||||||
networks:
|
|
||||||
proxy:
|
|
||||||
external: true
|
|
||||||
name: proxy
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copier ce fichier en .env et adapter les valeurs avant de démarrer.
|
||||||
|
# cp .env.example .env
|
||||||
|
|
||||||
|
# Mot de passe PostgreSQL partagé entre le container db et l'API Spring Boot.
|
||||||
|
POSTGRES_PASSWORD=changeme
|
||||||
|
|
||||||
|
# Chemin absolu vers la clé SSH privée ayant accès au dépôt Gitea.
|
||||||
|
SSH_KEY_PATH=/home/gato/.ssh/id_ed25519
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
FROM node:22-alpine AS builder
|
||||||
|
RUN apk add --no-cache git openssh
|
||||||
|
ARG CACHEBUST
|
||||||
|
RUN --mount=type=secret,id=ssh_key \
|
||||||
|
--mount=type=cache,target=/root/.npm \
|
||||||
|
mkdir -p /root/.ssh && \
|
||||||
|
cp /run/secrets/ssh_key /root/.ssh/id_ed25519 && \
|
||||||
|
chmod 600 /root/.ssh/id_ed25519 && \
|
||||||
|
ssh-keyscan -p 2222 git.goutailler-olivier.com >> /root/.ssh/known_hosts && \
|
||||||
|
git clone --depth 1 --branch main \
|
||||||
|
ssh://git@git.goutailler-olivier.com:2222/Gato/Bonsai-webapp.git /src && \
|
||||||
|
cd /src && npm ci --cache /root/.npm && npm run build
|
||||||
|
|
||||||
|
FROM nginx:alpine
|
||||||
|
COPY --from=builder /src/dist/Bonsai-webapp/browser /usr/share/nginx/html
|
||||||
|
COPY --from=builder /src/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
EXPOSE 80
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# Bonsai — Stack complète
|
||||||
|
|
||||||
|
Stack Docker Compose unifiée pour l'application Bonsai : base de données, API et webapp.
|
||||||
|
|
||||||
|
Les deux composants ne se déploient pas de la même façon :
|
||||||
|
|
||||||
|
- **`api`** — image **tirée du registre Gitea** (`git.goutailler-olivier.com/bonsai/bonsai-api:main`), publiée par la CI du dépôt `Bonsai-api` (`.gitea/workflows/images.yml`) à chaque merge sur `main`. Le redéploiement est automatique : le conteneur porte le label `com.centurylinklabs.watchtower.enable=true`, donc Watchtower (`../watchtower/`) le recrée dès qu'une nouvelle image est publiée. Rien à builder sur le serveur.
|
||||||
|
- **`webapp`** — toujours **buildé depuis les sources** de la branche `main` du dépôt `Bonsai-webapp`. La clé SSH est transmise au build via un secret BuildKit — elle n'est jamais gravée dans les couches de l'image.
|
||||||
|
|
||||||
|
## Services
|
||||||
|
|
||||||
|
| Service | Image | Provenance |
|
||||||
|
|---------|-------|------------|
|
||||||
|
| `db` | `postgres:16-alpine` | — |
|
||||||
|
| `api` | `git.goutailler-olivier.com/bonsai/bonsai-api:main` | CI de `Bonsai-api` (merge sur `main`) |
|
||||||
|
| `webapp` | `node:22-alpine` → `nginx:alpine` | build local depuis `Bonsai-webapp` (branche `main`) |
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
- Docker avec BuildKit activé (Docker 23+)
|
||||||
|
- Une clé SSH ayant accès au dépôt Gitea (`git.goutailler-olivier.com:2222`) — pour le build du `webapp`
|
||||||
|
- Réseau Docker externe `proxy` (Traefik)
|
||||||
|
- De quoi tirer les images privées de l'org **Bonsai** : soit un `docker login git.goutailler-olivier.com` fait une fois en root sur le serveur, soit les `REPO_USER`/`REPO_PASS` de la stack Watchtower, dont le PAT doit porter le scope `read:package` sur l'org Bonsai. Sans cela, Watchtower échoue silencieusement à tirer l'image (`unauthorized: reqPackageAccess`) et la prod reste sur l'ancienne version, alors que l'appel à `/v1/update` répond bien 200.
|
||||||
|
|
||||||
|
## Démarrage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Configurer les variables d'environnement
|
||||||
|
cp .env.example .env
|
||||||
|
# Éditer .env : définir POSTGRES_PASSWORD et SSH_KEY_PATH
|
||||||
|
|
||||||
|
# 2. Tirer l'image de l'API + builder le webapp
|
||||||
|
docker compose pull
|
||||||
|
docker compose build
|
||||||
|
|
||||||
|
# 3. Démarrer la stack
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mise à jour
|
||||||
|
|
||||||
|
L'API se met à jour **toute seule** à chaque merge sur `main` de `Bonsai-api` (CI → registre → Watchtower). Aucune action ici.
|
||||||
|
|
||||||
|
Pour forcer un redéploiement, ou pour rebuilder le webapp depuis le dernier commit de sa branche `main` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
`CACHEBUST` (posé par le script) invalide uniquement l'étape clone+build du webapp. Les couches précédentes (installation des outils, image de base) restent en cache — le build reste rapide.
|
||||||
|
|
||||||
|
### Revenir à une version précédente de l'API
|
||||||
|
|
||||||
|
Chaque publication pose aussi un tag immuable `sha-<court>`. Pour épingler un commit :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
image: git.goutailler-olivier.com/bonsai/bonsai-api:sha-ccc20bf
|
||||||
|
```
|
||||||
|
|
||||||
|
puis `docker compose up -d api`. Watchtower ne touche pas à un tag figé qui ne bouge plus — repasser sur `:main` pour réactiver le suivi automatique.
|
||||||
|
|
||||||
|
## Arrêt
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
Les données PostgreSQL sont persistées dans `~/Applications/data/bonsai/db_data` et les fichiers uploadés dans `~/Applications/data/bonsai/uploads`.
|
||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Déploiement manuel de la stack Bonsai.
|
||||||
|
#
|
||||||
|
# L'API n'est plus buildée ici : son image est publiée par la CI du dépôt
|
||||||
|
# Bonsai-api à chaque merge sur main, et Watchtower recrée le conteneur tout seul.
|
||||||
|
# Ce script sert donc au premier démarrage, à un changement de la stack ou à un
|
||||||
|
# redéploiement forcé — « pull » va chercher la dernière image de l'API, « build »
|
||||||
|
# ne concerne plus que le webapp (toujours compilé depuis les sources).
|
||||||
|
|
||||||
|
docker compose pull
|
||||||
|
CACHEBUST=$(date +%s) docker compose build
|
||||||
|
docker compose up -d
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
name: bonsai
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: bonsai-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: bonsai
|
||||||
|
POSTGRES_USER: bonsai
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
TZ: Europe/Paris
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U bonsai -d bonsai"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- ~/Applications/data/bonsai/db_data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- bonsai-net
|
||||||
|
|
||||||
|
# Image tirée du registre Gitea, publiée par la CI du dépôt Bonsai-api
|
||||||
|
# (.gitea/workflows/images.yml) à chaque push sur main. Le tag « main » suit la
|
||||||
|
# tête de cette branche ; « sha-<court> » permet d'épingler un commit précis en
|
||||||
|
# cas de rollback.
|
||||||
|
#
|
||||||
|
# Avant, ce service clonait le dépôt et compilait le JAR sur le serveur à chaque
|
||||||
|
# « docker compose build » (Dockerfile.api + secret ssh_key + CACHEBUST) : la prod
|
||||||
|
# rebuildait ce que la CI avait déjà buildé, et rien ne garantissait que les deux
|
||||||
|
# partaient du même commit. Le redéploiement est désormais automatique — le label
|
||||||
|
# watchtower.enable ci-dessous fait recréer ce conteneur dès que la CI publie une
|
||||||
|
# nouvelle image.
|
||||||
|
#
|
||||||
|
# Prérequis : le serveur doit pouvoir tirer les images privées de l'org Bonsai —
|
||||||
|
# soit via un « docker login git.goutailler-olivier.com » (root), soit via les
|
||||||
|
# REPO_USER/REPO_PASS de la stack Watchtower, dont le PAT doit avoir le scope
|
||||||
|
# read:package sur l'org Bonsai (et pas seulement sur Luz).
|
||||||
|
api:
|
||||||
|
image: git.goutailler-olivier.com/bonsai/bonsai-api:main
|
||||||
|
container_name: bonsai-api
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
DATASOURCE_URL: jdbc:postgresql://db:5432/bonsai
|
||||||
|
DATASOURCE_USERNAME: bonsai
|
||||||
|
DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
KEYCLOAK_JWKS_URI: https://auth.goutailler-olivier.com/realms/bonsai/protocol/openid-connect/certs
|
||||||
|
CORS_ALLOWED_ORIGIN_PROD: https://bonsai.goutailler-olivier.com
|
||||||
|
SERVER_SERVLET_CONTEXT_PATH: /api
|
||||||
|
TZ: Europe/Paris
|
||||||
|
volumes:
|
||||||
|
- ~/Applications/data/bonsai/uploads:/app/uploads
|
||||||
|
networks:
|
||||||
|
- bonsai-net
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.bonsai-api.rule=Host(`bonsai.goutailler-olivier.com`) && PathPrefix(`/api`)
|
||||||
|
- traefik.http.routers.bonsai-api.entrypoints=websecure
|
||||||
|
- traefik.http.routers.bonsai-api.tls.certresolver=le
|
||||||
|
- traefik.http.services.bonsai-api.loadbalancer.server.port=8080
|
||||||
|
- traefik.docker.network=proxy
|
||||||
|
|
||||||
|
webapp:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.webapp
|
||||||
|
secrets:
|
||||||
|
- ssh_key
|
||||||
|
args:
|
||||||
|
CACHEBUST: ${CACHEBUST:-stable}
|
||||||
|
container_name: bonsai-webapp
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Paris
|
||||||
|
networks:
|
||||||
|
- bonsai-net
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.bonsai-webapp.rule=Host(`bonsai.goutailler-olivier.com`)
|
||||||
|
- traefik.http.routers.bonsai-webapp.entrypoints=websecure
|
||||||
|
- traefik.http.routers.bonsai-webapp.tls.certresolver=le
|
||||||
|
- traefik.http.services.bonsai-webapp.loadbalancer.server.port=80
|
||||||
|
- traefik.docker.network=proxy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
bonsai-net:
|
||||||
|
driver: bridge
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
name: proxy
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
ssh_key:
|
||||||
|
file: ${SSH_KEY_PATH}
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# Stack de TEST Luz — dev-luz.goutailler-olivier.com
|
||||||
|
#
|
||||||
|
# Frontend : https://dev-luz.goutailler-olivier.com → webapp (nginx :80)
|
||||||
|
# Backend : https://dev-luz.goutailler-olivier.com/api → backend Spring (:8080)
|
||||||
|
#
|
||||||
|
# Déploiement AUTOMATIQUE : la CI Gitea (client/app/.gitea/workflows/images.yml)
|
||||||
|
# builde et pousse les images « …/luz/luz-*:main » à chaque push sur main,
|
||||||
|
# puis appelle l'API HTTP de Watchtower. Watchtower (../watchtower/) ne surveille
|
||||||
|
# que les conteneurs portant le label watchtower.enable=true (posé ci-dessous) :
|
||||||
|
# il tire la nouvelle image et recrée le conteneur. Plus de transfert SSH ni de
|
||||||
|
# « deploy.sh » pour cette stack de test.
|
||||||
|
#
|
||||||
|
# ⚠️ La CI ne publie plus « :develop » (elle ne se déclenche que sur main) : une
|
||||||
|
# stack restée sur ce tag ne reçoit plus jamais de mise à jour, en silence. Le tag
|
||||||
|
# suivi ici doit toujours être celui que publie images.yml — cf. ../luz/.
|
||||||
|
#
|
||||||
|
# Prérequis : le serveur (root) doit être « docker login git.goutailler-olivier.com »
|
||||||
|
# une fois, sinon Watchtower ne peut pas tirer les images privées de l'org luz.
|
||||||
|
#
|
||||||
|
# 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 « dev-luz » pointant sur le serveur (Let's Encrypt HTTP-01).
|
||||||
|
name: dev-luz
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgres:17
|
||||||
|
container_name: dev-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:
|
||||||
|
- dev_luz_db:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- dev-luz-net
|
||||||
|
|
||||||
|
backend:
|
||||||
|
image: git.goutailler-olivier.com/luz/luz-backend:main
|
||||||
|
container_name: dev-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}
|
||||||
|
SPRING_PROFILES_ACTIVE: dev # TRUNCATE + rejeu de seed.sql à chaque démarrage
|
||||||
|
TZ: Europe/Paris
|
||||||
|
networks:
|
||||||
|
- dev-luz-net
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.dev-luz-backend.rule=Host(`dev-luz.goutailler-olivier.com`) && PathPrefix(`/api`)
|
||||||
|
- traefik.http.routers.dev-luz-backend.entrypoints=websecure
|
||||||
|
- traefik.http.routers.dev-luz-backend.tls.certresolver=le
|
||||||
|
- traefik.http.services.dev-luz-backend.loadbalancer.server.port=8080
|
||||||
|
- traefik.docker.network=proxy
|
||||||
|
|
||||||
|
webapp:
|
||||||
|
image: git.goutailler-olivier.com/luz/luz-webapp:main
|
||||||
|
container_name: dev-luz-webapp
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Paris
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.dev-luz-webapp.rule=Host(`dev-luz.goutailler-olivier.com`)
|
||||||
|
- traefik.http.routers.dev-luz-webapp.entrypoints=websecure
|
||||||
|
- traefik.http.routers.dev-luz-webapp.tls.certresolver=le
|
||||||
|
- traefik.http.services.dev-luz-webapp.loadbalancer.server.port=80
|
||||||
|
- traefik.docker.network=proxy
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
dev_luz_db:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
dev-luz-net:
|
||||||
|
driver: bridge
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
name: proxy
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Copier ce fichier en .env et renseigner les valeurs avant de démarrer.
|
||||||
|
# cp env.example .env
|
||||||
|
|
||||||
|
# Mot de passe PostgreSQL pour la base de données Gitea.
|
||||||
|
GITEA_POSTGRES_PASSWORD=changeme
|
||||||
|
|
||||||
|
# Token d'enregistrement du runner Gitea Actions.
|
||||||
|
# À récupérer dans Gitea : Site Administration > Actions > Runners > Create new runner
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN=your_runner_token_here
|
||||||
@@ -8,7 +8,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: gitea
|
POSTGRES_DB: gitea
|
||||||
POSTGRES_USER: gitea
|
POSTGRES_USER: gitea
|
||||||
POSTGRES_PASSWORD: change_me
|
POSTGRES_PASSWORD: ${GITEA_POSTGRES_PASSWORD}
|
||||||
TZ: Europe/Paris
|
TZ: Europe/Paris
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||||
@@ -47,7 +47,7 @@ services:
|
|||||||
GITEA__database__HOST: db:5432
|
GITEA__database__HOST: db:5432
|
||||||
GITEA__database__NAME: gitea
|
GITEA__database__NAME: gitea
|
||||||
GITEA__database__USER: gitea
|
GITEA__database__USER: gitea
|
||||||
GITEA__database__PASSWD: change_me
|
GITEA__database__PASSWD: ${GITEA_POSTGRES_PASSWORD}
|
||||||
|
|
||||||
TZ: Europe/Paris
|
TZ: Europe/Paris
|
||||||
volumes:
|
volumes:
|
||||||
@@ -88,7 +88,7 @@ services:
|
|||||||
- gitea
|
- gitea
|
||||||
environment:
|
environment:
|
||||||
GITEA_INSTANCE_URL: http://gitea:3000
|
GITEA_INSTANCE_URL: http://gitea:3000
|
||||||
GITEA_RUNNER_REGISTRATION_TOKEN: VBV30irSexdiyvHyzlX0HAmb1iV3XGiDm37raumU
|
GITEA_RUNNER_REGISTRATION_TOKEN: ${GITEA_RUNNER_REGISTRATION_TOKEN}
|
||||||
GITEA_RUNNER_NAME: docker-runner
|
GITEA_RUNNER_NAME: docker-runner
|
||||||
GITEA_RUNNER_LABELS: ubuntu-latest:host
|
GITEA_RUNNER_LABELS: ubuntu-latest:host
|
||||||
CONFIG_FILE: /config.yaml
|
CONFIG_FILE: /config.yaml
|
||||||
|
|||||||
@@ -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
|
||||||
+89
-11
@@ -1,27 +1,105 @@
|
|||||||
|
# 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)
|
||||||
|
#
|
||||||
|
# Images tirées du registre Gitea (git.goutailler-olivier.com/luz/luz-*:main),
|
||||||
|
# publiées par la CI (client/app/.gitea/workflows/images.yml) à chaque push « main »
|
||||||
|
# — c'est-à-dire à chaque mise en production. Prod et dev-luz partagent donc la MÊME
|
||||||
|
# image ; ce qui les sépare : ici la base est PERSISTANTE et sans profil « dev » (voir
|
||||||
|
# plus bas), côté dev-luz elle est réinitialisée à chaque démarrage. Le redéploiement
|
||||||
|
# est automatique : les conteneurs portent le label watchtower.enable=true, donc chaque
|
||||||
|
# push main fait recréer AUSSI cette prod par Watchtower (../watchtower/), en même
|
||||||
|
# temps que dev-luz. Plus de transfert SSH ni de deploy.sh.
|
||||||
|
#
|
||||||
|
# ⚠️ Le tag suivi ici doit rester celui que la CI publie. L'app a d'abord publié
|
||||||
|
# « :develop » (elle n'avait pas de branche main), puis est passée à « :main ». Ces
|
||||||
|
# stacks étant restées sur « :develop », plus rien n'a poussé ce tag : Watchtower
|
||||||
|
# répondait 200 à /v1/update mais ne trouvait aucune image plus récente, et la prod
|
||||||
|
# est restée figée sur le dernier build develop (a70e0e4, 25/07) pendant que main
|
||||||
|
# avançait de 79 commits — sans la moindre erreur visible côté CI hors la
|
||||||
|
# vérification post-déploiement. Changer le tag de publication dans images.yml
|
||||||
|
# impose donc de changer ce tag ici, dans le même mouvement.
|
||||||
|
#
|
||||||
|
# Prérequis : le serveur (root) doit être « docker login git.goutailler-olivier.com »
|
||||||
|
# une fois, sinon Watchtower ne peut pas tirer les images privées de l'org luz.
|
||||||
|
#
|
||||||
|
# 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
|
name: luz
|
||||||
|
|
||||||
services:
|
services:
|
||||||
luz:
|
db:
|
||||||
image: git.goutailler-olivier.com/gato/luz:latest
|
image: postgres:17
|
||||||
container_name: luz
|
container_name: luz-db
|
||||||
restart: unless-stopped
|
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: git.goutailler-olivier.com/luz/luz-backend:main
|
||||||
|
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:
|
||||||
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
- 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: git.goutailler-olivier.com/luz/luz-webapp:main
|
||||||
|
container_name: luz-webapp
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
environment:
|
environment:
|
||||||
TZ: Europe/Paris
|
TZ: Europe/Paris
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.luz.rule=Host(`luz.goutailler-olivier.com`)
|
|
||||||
- traefik.http.routers.luz.entrypoints=websecure
|
|
||||||
- traefik.http.routers.luz.tls.certresolver=le
|
|
||||||
- traefik.http.services.luz.loadbalancer.server.port=80
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- com.centurylinklabs.watchtower.enable=true
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.luz-webapp.rule=Host(`luz.goutailler-olivier.com`)
|
||||||
|
- traefik.http.routers.luz-webapp.entrypoints=websecure
|
||||||
|
- traefik.http.routers.luz-webapp.tls.certresolver=le
|
||||||
|
- traefik.http.services.luz-webapp.loadbalancer.server.port=80
|
||||||
|
- traefik.docker.network=proxy
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
luz-net:
|
||||||
|
driver: bridge
|
||||||
proxy:
|
proxy:
|
||||||
external: true
|
external: true
|
||||||
name: proxy
|
name: proxy
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Copier ce fichier en .env et renseigner les valeurs avant de démarrer.
|
||||||
|
# cp env.example .env
|
||||||
|
|
||||||
|
# Mot de passe PostgreSQL partagé entre le container db et Nextcloud.
|
||||||
|
POSTGRES_PASSWORD=changeme
|
||||||
|
|
||||||
|
# Compte administrateur Nextcloud — créé uniquement au premier démarrage.
|
||||||
|
# Pour le modifier après initialisation, passer par l'interface d'administration.
|
||||||
|
NEXTCLOUD_ADMIN_USER=admin
|
||||||
|
NEXTCLOUD_ADMIN_PASSWORD=changeme
|
||||||
|
|
||||||
|
# Identifiants pgAdmin (interface web d'administration PostgreSQL).
|
||||||
|
PGADMIN_DEFAULT_EMAIL=admin@example.com
|
||||||
|
PGADMIN_DEFAULT_PASSWORD=changeme
|
||||||
@@ -13,7 +13,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: nextcloud
|
POSTGRES_DB: nextcloud
|
||||||
POSTGRES_USER: nextcloud
|
POSTGRES_USER: nextcloud
|
||||||
POSTGRES_PASSWORD: changeme
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
TZ: Europe/Paris
|
TZ: Europe/Paris
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||||
@@ -36,10 +36,10 @@ services:
|
|||||||
POSTGRES_HOST: db
|
POSTGRES_HOST: db
|
||||||
POSTGRES_DB: nextcloud
|
POSTGRES_DB: nextcloud
|
||||||
POSTGRES_USER: nextcloud
|
POSTGRES_USER: nextcloud
|
||||||
POSTGRES_PASSWORD: changeme
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
|
||||||
NEXTCLOUD_ADMIN_USER: admin
|
NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER}
|
||||||
NEXTCLOUD_ADMIN_PASSWORD: adminpass
|
NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD}
|
||||||
|
|
||||||
NEXTCLOUD_TRUSTED_DOMAINS: cloud.goutailler-olivier.com
|
NEXTCLOUD_TRUSTED_DOMAINS: cloud.goutailler-olivier.com
|
||||||
NEXTCLOUD_OVERWRITEHOST: cloud.goutailler-olivier.com
|
NEXTCLOUD_OVERWRITEHOST: cloud.goutailler-olivier.com
|
||||||
@@ -77,8 +77,8 @@ services:
|
|||||||
container_name: nextcloud-pgadmin
|
container_name: nextcloud-pgadmin
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
PGADMIN_DEFAULT_EMAIL: admin@example.com
|
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
|
||||||
PGADMIN_DEFAULT_PASSWORD: adminpass
|
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
|
||||||
PGADMIN_CONFIG_SERVER_MODE: 'False'
|
PGADMIN_CONFIG_SERVER_MODE: 'False'
|
||||||
TZ: Europe/Paris
|
TZ: Europe/Paris
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
name: olhar-api-stack
|
|
||||||
|
|
||||||
services:
|
|
||||||
db:
|
|
||||||
image: postgres:16-alpine
|
|
||||||
container_name: olhar-api-db
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: olhar
|
|
||||||
POSTGRES_USER: olhar
|
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
TZ: Europe/Paris
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U olhar -d olhar"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
volumes:
|
|
||||||
- ~/Applications/data/olhar-api/db_data:/var/lib/postgresql/data
|
|
||||||
networks:
|
|
||||||
- olhar-api-net
|
|
||||||
|
|
||||||
api:
|
|
||||||
image: git.goutailler-olivier.com/gato/olhar-api:latest
|
|
||||||
container_name: olhar-api
|
|
||||||
restart: unless-stopped
|
|
||||||
depends_on:
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
environment:
|
|
||||||
DATASOURCE_URL: jdbc:postgresql://db:5432/olhar
|
|
||||||
DATASOURCE_USERNAME: olhar
|
|
||||||
DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
KEYCLOAK_JWKS_URI: https://auth.goutailler-olivier.com/realms/olhar/protocol/openid-connect/certs
|
|
||||||
CORS_ALLOWED_ORIGIN_PROD: https://olhar.goutailler-olivier.com
|
|
||||||
TZ: Europe/Paris
|
|
||||||
networks:
|
|
||||||
- olhar-api-net
|
|
||||||
- proxy
|
|
||||||
labels:
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.olhar-api.rule=Host(`olhar.goutailler-olivier.com`) && PathPrefix(`/api`)
|
|
||||||
- traefik.http.routers.olhar-api.entrypoints=websecure
|
|
||||||
- traefik.http.routers.olhar-api.tls.certresolver=le
|
|
||||||
- traefik.http.services.olhar-api.loadbalancer.server.port=8080
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- com.centurylinklabs.watchtower.enable=true
|
|
||||||
|
|
||||||
networks:
|
|
||||||
olhar-api-net:
|
|
||||||
driver: bridge
|
|
||||||
proxy:
|
|
||||||
external: true
|
|
||||||
name: proxy
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Copier en .env et définir des valeurs sécurisées avant de démarrer.
|
||||||
|
# cp .env.example .env
|
||||||
|
|
||||||
|
# Mot de passe PostgreSQL partagé entre le container db et l'API Spring Boot.
|
||||||
|
POSTGRES_PASSWORD=changeme
|
||||||
|
|
||||||
|
# Secret JWT utilisé pour signer les tokens d'authentification.
|
||||||
|
# Générer une valeur forte : openssl rand -hex 32
|
||||||
|
JWT_SECRET=changeme-in-production-use-a-long-random-string-at-least-256-bits
|
||||||
|
|
||||||
|
# Dossier racine pour les données persistantes (BDD + uploads).
|
||||||
|
# La BDD sera dans ${DATA_PATH}/olhar/db_data
|
||||||
|
# Les photos dans ${DATA_PATH}/olhar/uploads
|
||||||
|
DATA_PATH=/home/gato/Applications/data
|
||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_URL="ssh://git@git.goutailler-olivier.com:2222/Gato/Olhar.git"
|
||||||
|
BUILD_DIR="${HOME}/Applications/build/Olhar"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# ── 1. Récupérer les sources ──────────────────────────────────────────────────
|
||||||
|
if [ -d "${BUILD_DIR}/.git" ]; then
|
||||||
|
echo "▶ Mise à jour du dépôt (develop)..."
|
||||||
|
git -C "${BUILD_DIR}" fetch origin develop
|
||||||
|
git -C "${BUILD_DIR}" reset --hard origin/develop
|
||||||
|
else
|
||||||
|
echo "▶ Clonage du dépôt..."
|
||||||
|
git clone --branch develop --depth 1 "${REPO_URL}" "${BUILD_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 2. Build & démarrage du stack ────────────────────────────────────────────
|
||||||
|
echo "▶ Build des images et démarrage du stack..."
|
||||||
|
docker compose \
|
||||||
|
-f "${BUILD_DIR}/docker-compose.yml" \
|
||||||
|
--env-file "${SCRIPT_DIR}/.env" \
|
||||||
|
up --build -d
|
||||||
|
|
||||||
|
echo "✓ Stack démarré."
|
||||||
@@ -1,17 +1,62 @@
|
|||||||
name: olhar
|
name: olhar
|
||||||
|
|
||||||
services:
|
services:
|
||||||
oalhar:
|
db:
|
||||||
image: git.goutailler-olivier.com/gato/olhar-pwa:latest
|
image: postgres:16-alpine
|
||||||
container_name: olhar
|
container_name: olhar-db
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: olhar
|
||||||
|
POSTGRES_USER: olhar
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
TZ: Europe/Paris
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U olhar -d olhar"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- ~/Applications/data/olhar/db_data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- olhar-net
|
||||||
|
|
||||||
|
api:
|
||||||
|
image: git.goutailler-olivier.com/gato/olhar-api:latest
|
||||||
|
container_name: olhar-api
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
DATASOURCE_URL: jdbc:postgresql://db:5432/olhar
|
||||||
|
DATASOURCE_USERNAME: olhar
|
||||||
|
DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
JWT_SECRET: ${JWT_SECRET}
|
||||||
|
CORS_ALLOWED_ORIGIN_PROD: https://olhar.goutailler-olivier.com
|
||||||
|
PHOTOS_STORAGE_PATH: /app/uploads
|
||||||
|
TZ: Europe/Paris
|
||||||
|
volumes:
|
||||||
|
- ~/Applications/data/olhar/uploads:/app/uploads
|
||||||
|
networks:
|
||||||
|
- olhar-net
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.olhar-api.rule=Host(`olhar.goutailler-olivier.com`) && PathPrefix(`/api`)
|
||||||
|
- traefik.http.routers.olhar-api.entrypoints=websecure
|
||||||
|
- traefik.http.routers.olhar-api.tls.certresolver=le
|
||||||
|
- traefik.http.services.olhar-api.loadbalancer.server.port=8080
|
||||||
|
- traefik.docker.network=proxy
|
||||||
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
|
||||||
|
pwa:
|
||||||
|
image: git.goutailler-olivier.com/gato/olhar-pwa:latest
|
||||||
|
container_name: olhar-pwa
|
||||||
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
TZ: Europe/Paris
|
TZ: Europe/Paris
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
- traefik.enable=true
|
||||||
- traefik.http.routers.olhar.rule=Host(`olhar.goutailler-olivier.com`)
|
- traefik.http.routers.olhar.rule=Host(`olhar.goutailler-olivier.com`)
|
||||||
@@ -22,6 +67,8 @@ services:
|
|||||||
- com.centurylinklabs.watchtower.enable=true
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
olhar-net:
|
||||||
|
driver: bridge
|
||||||
proxy:
|
proxy:
|
||||||
external: true
|
external: true
|
||||||
name: proxy
|
name: proxy
|
||||||
|
|||||||
@@ -1 +1,9 @@
|
|||||||
|
# Jeton d'authentification de l'API HTTP de Watchtower (déclenchement du /v1/update
|
||||||
|
# par la CI). Doit être identique au secret WATCHTOWER_TOKEN côté Gitea Actions.
|
||||||
WATCHTOWER_TOKEN=votre_token_secret_ici
|
WATCHTOWER_TOKEN=votre_token_secret_ici
|
||||||
|
|
||||||
|
# Identifiants de pull du registre Gitea privé (git.goutailler-olivier.com).
|
||||||
|
# PAT en LECTURE seule (scope read:package) d'un compte membre de l'org Luz.
|
||||||
|
# Utilisés par Watchtower (REPO_USER/REPO_PASS) pour tirer luz-backend/luz-webapp.
|
||||||
|
REGISTRY_USER=nom_utilisateur_gitea
|
||||||
|
REGISTRY_PASS=pat_read_package_ici
|
||||||
|
|||||||
@@ -7,12 +7,23 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- /root/.docker/config.json:/root/.docker/config.json:ro
|
|
||||||
environment:
|
environment:
|
||||||
WATCHTOWER_HTTP_API_UPDATE: "true"
|
WATCHTOWER_HTTP_API_UPDATE: "true"
|
||||||
WATCHTOWER_HTTP_API_TOKEN: ${WATCHTOWER_TOKEN}
|
WATCHTOWER_HTTP_API_TOKEN: ${WATCHTOWER_TOKEN}
|
||||||
WATCHTOWER_LABEL_ENABLE: "true"
|
WATCHTOWER_LABEL_ENABLE: "true"
|
||||||
WATCHTOWER_CLEANUP: "true"
|
WATCHTOWER_CLEANUP: "true"
|
||||||
|
# Identifiants de pull du registre Gitea privé (git.goutailler-olivier.com).
|
||||||
|
# Sans eux, Watchtower échoue à tirer luz-backend/luz-webapp :main
|
||||||
|
# (« unauthorized: reqPackageAccess ») et ne recrée jamais les conteneurs
|
||||||
|
# — le déploiement reste bloqué en silence (Updated=0, mais /v1/update → 200).
|
||||||
|
# Un PAT en LECTURE seule (scope read:package) suffit — mais il lui faut
|
||||||
|
# accès aux DEUX organisations qui publient des images ici : Luz et, depuis
|
||||||
|
# que la stack bonsai tire bonsai-api du registre, Bonsai. Un PAT limité à
|
||||||
|
# Luz laisserait la prod Bonsai bloquée sur son ancienne image, en silence.
|
||||||
|
# Remplace l'ancien montage de /root/.docker/config.json, qui côté hôte
|
||||||
|
# ne contenait aucune auth (le docker login du CI a lieu sur le runner).
|
||||||
|
REPO_USER: ${REGISTRY_USER}
|
||||||
|
REPO_PASS: ${REGISTRY_PASS}
|
||||||
TZ: Europe/Paris
|
TZ: Europe/Paris
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
|
|||||||
Reference in New Issue
Block a user