Files
Gato 30887c066b feat(bonsai): la prod tire l'image publiée par la CI au lieu de la recompiler
Le service api 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 donc ce que la CI avait déjà buildé, sans garantie que les deux
partent du même commit — et aucune image publiée n'atteignait jamais la prod.

Elle tire maintenant …/bonsai-api:main et porte le label watchtower.enable : le
redéploiement suit tout seul chaque merge sur main, comme pour Luz. Le webapp,
lui, continue d'être buildé depuis les sources — d'où le secret ssh_key conservé.

Prérequis : de quoi tirer les images privées de l'org Bonsai. Le PAT de Watchtower
n'a aujourd'hui le scope read:package que sur Luz ; sans extension à Bonsai, le
pull échoue en silence (/v1/update répond 200, la prod ne bouge pas).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 14:02:24 +02:00

3.1 KiB

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-alpinenginx: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

# 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 :

./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 :

    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

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.