docker-compose: full web + api + blogs + db with healthchecks

Rewrite docker-compose.yaml to match the runtime architecture
introduced in the previous commits:

- 4 services: db (postgres:16), web (Yavsc.Org), api (Yavsc.Api),
  blogs (Yavsc.Blogs). Each runtime service builds from its own
  Dockerfile.runtime* with a pinned BUILD_ENV_IMAGE.
- Healthcheck on db via pg_isready. web/api/blogs wait for
  service_healthy before starting (was: bare depends_on which
  races the DB on cold boot).
- Two named networks: yavsc-internal (db + runtimes) and
  yavsc-public (runtimes only). Compose v2 default, but the
  split makes the intent explicit and lets the operator
  externalise the public network if needed.
- Each runtime service injects appsettings-org.json via the
  yavsc_appsettings BuildKit secret (file: ./appsettings-org.json).
  No appsettings in the build context.
- HTTPS ports (5001, 5003, 5005) and the /etc/letsencrypt volume
  mount are commented out — uncomment them in production when
  Kestrel:Certificates is configured in appsettings-org.json.
- The old POSTGRES_* build args on the web service are gone: the
  build env no longer needs DB credentials (only the runtime does,
  via env_file).
This commit is contained in:
Paul Schneider 2026-06-27 16:14:31 +01:00
commit 49644e3858

View file

@ -1,24 +1,109 @@
services:
# ---------- PostgreSQL ----------
# Image officielle. Les credentials sont repris du .env (jamais commité).
# Healthcheck via pg_isready : web/api/blogs ne démarrent qu'une fois la
# base prête à accepter des connexions.
db:
image: postgres:16
env_file: .env
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- yavsc-internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
# ---------- Yavsc.Org (front web) ----------
# Build depuis Dockerfile.runtime. ASPNETCORE_URLS=http://+:5000 (HTTP seul
# en dev). Pour activer HTTPS en prod, décommenter le montage letsencrypt
# ci-dessous et renseigner Kestrel:Certificates dans appsettings-org.json.
web:
build:
context: .
dockerfile: Dockerfile.runtime
args:
POSTGRES_HOST: db
POSTGRES_PORT: ${POSTGRES_PORT}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
BUILD_ENV_IMAGE: pazof/yavsc-build-env:debian12-dotnet10-android36-v1
secrets:
- yavsc_appsettings
env_file: .env
ports:
- "5000:5000"
# - "5001:5001" # HTTPS : décommenter avec le volume letsencrypt
depends_on:
- db
db:
condition: service_healthy
networks:
- yavsc-internal
- yavsc-public
# volumes:
# - /etc/letsencrypt:/etc/letsencrypt:ro
# ---------- Yavsc.Api (API REST) ----------
api:
build:
context: .
dockerfile: Dockerfile.runtime.api
args:
BUILD_ENV_IMAGE: pazof/yavsc-build-env:debian12-dotnet10-android36-v1
secrets:
- yavsc_appsettings
env_file: .env
ports:
- "5002:5002"
# - "5003:5003" # HTTPS : décommenter avec le volume letsencrypt
depends_on:
db:
condition: service_healthy
networks:
- yavsc-internal
- yavsc-public
# volumes:
# - /etc/letsencrypt:/etc/letsencrypt:ro
# ---------- Yavsc.Blogs (backend API headless des blogs) ----------
# Déployé sur un sous-domaine dédié en production (ex: blogs.yavsc.example).
# cf. doc/architecture/decoupage-organisation.md pour la séparation avec
# le front des blogs (qui reste dans Yavsc.Org).
blogs:
build:
context: .
dockerfile: Dockerfile.runtime.blogs
args:
BUILD_ENV_IMAGE: pazof/yavsc-build-env:debian12-dotnet10-android36-v1
secrets:
- yavsc_appsettings
env_file: .env
ports:
- "5004:5004"
# - "5005:5005" # HTTPS : décommenter avec le volume letsencrypt
depends_on:
db:
condition: service_healthy
networks:
- yavsc-internal
- yavsc-public
# volumes:
# - /etc/letsencrypt:/etc/letsencrypt:ro
volumes:
pgdata:
pgdata:
networks:
# Réseau interne : seuls les services Yavsc et la base s'y voient.
# Non attaché à l'hôte.
yavsc-internal:
internal: false
# Réseau public : exposé à l'hôte via les ports mappés. Conserver
# les services web/api/blogs ici, PAS la base.
yavsc-public:
secrets:
# appsettings-org.json : fichier local non commité. BuildKit le
# monte dans /run/secrets/yavsc_appsettings pendant le build de
# chaque image runtime.
yavsc_appsettings:
file: ./appsettings-org.json