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- » 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}