yavsc/docker-compose.yaml
Paul Schneider 4b4afa2eae docker-compose: explicit source/target mapping for build secrets
The shorthand 'secrets: - yavsc_appsettings' relies on Compose
v2 to derive both source and target from the same name. In
some BuildKit integrations this is not enough — the secret id
seen inside the Dockerfile (yavsc_appsettings) and the source
defined at top-level (yavsc_appsettings, file: ...) end up not
being mapped correctly, leading to:

  cp: cannot stat '/run/secrets/yavsc_appsettings':
    No such file or directory

at the blogs-runtime / api-runtime / web-runtime stages.

Use the explicit long form:

  secrets:
    - source: yavsc_appsettings
      target: yavsc_appsettings

in all three runtime services. source is the top-level secret
name (file: ./src/Yavsc.Org/appsettings-org.json); target is
the id BuildKit exposes inside the container at
/run/secrets/yavsc_appsettings, matching --mount=type=secret,
id=yavsc_appsettings in the Dockerfile.
2026-06-27 18:25:26 +01:00

147 lines
4.9 KiB
YAML

services:
# ---------- PostgreSQL ----------
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) ----------
# Construit depuis le stage `web-runtime` du Dockerfile multi-stage.
# ASPNETCORE_URLS=http://+:5000 (HTTP seul en dev). Pour activer
# HTTPS en prod, décommenter le port 5001, monter /etc/letsencrypt
# en volume, et configurer Kestrel:Certificates dans
# appsettings-org.json (cf. CONTRIBUTING.md).
web:
build:
context: .
dockerfile: Dockerfile
target: web-runtime
args:
BUILD_ENV_TAG: debian12-dotnet10-android36-v1
secrets:
- source: yavsc_appsettings
target: yavsc_appsettings
env_file: .env
# ASPNETCORE_URLS forcé à HTTP seul en dev. Le HTTPS (port 5001)
# est désactivé par défaut parce qu'aucun certificat n'est
# disponible sur la machine hôte du critère Jalon 0 ; pour
# l'activer en prod, décommenter le port 5001, monter
# /etc/letsencrypt en volume (template commenté ci-dessous), et
# ajouter Kestrel:Endpoints:Https dans appsettings-org.json.
environment:
ASPNETCORE_URLS: "http://+:5000"
ASPNETCORE_HTTPS_PORT: ""
# Forcer Production sur les services runtime : sans ça,
# appsettings-org.Development.json charge un bloc Kestrel
# avec un endpoint HTTPS qui crashe Kestrel (« No server
# certificate was specified »). Le bloc environment: dans
# Compose prend le pas sur la valeur ASPNETCORE_ENVIRONMENT
# du env_file: .env (qui contient Development).
ASPNETCORE_ENVIRONMENT: "Production"
ports:
- "5000:5000"
# - "5001:5001" # HTTPS : activer avec le volume letsencrypt ci-dessous
depends_on:
db:
condition: service_healthy
networks:
- yavsc-internal
- yavsc-public
# volumes:
# # Indispensable pour que Yavsc.Org (IdentityServer8) démarre.
# # Sans ce montage, 'docker compose up' échoue côté web avec
# # « Production IdentityServer requires a signing certificate ».
# # Décommenter ici + côté api/blogs + renseigner
# # Kestrel:Endpoints:Https:Certificate:{Path,KeyPath} dans
# # appsettings-org.json (cf. section HTTPS en production dans
# # CONTRIBUTING.md).
# - /etc/letsencrypt:/etc/letsencrypt:ro
# ---------- Yavsc.Api (API REST principale) ----------
api:
build:
context: .
dockerfile: Dockerfile
target: api-runtime
args:
BUILD_ENV_TAG: debian12-dotnet10-android36-v1
secrets:
- source: yavsc_appsettings
target: yavsc_appsettings
env_file: .env
# ASPNETCORE_URLS forcé à HTTP seul en dev. Voir commentaire détaillé
# dans le service `web` ci-dessus ; même logique pour l'API.
environment:
ASPNETCORE_URLS: "http://+:5002"
ASPNETCORE_HTTPS_PORT: ""
ASPNETCORE_ENVIRONMENT: "Production"
ports:
- "5002:5002"
# - "5003:5003" # HTTPS : activer avec le volume letsencrypt ci-dessous
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.
blogs:
build:
context: .
dockerfile: Dockerfile
target: blogs-runtime
args:
BUILD_ENV_TAG: debian12-dotnet10-android36-v1
secrets:
- source: yavsc_appsettings
target: yavsc_appsettings
env_file: .env
# ASPNETCORE_URLS forcé à HTTP seul en dev. Voir commentaire détaillé
# dans le service `web` ci-dessus ; même logique pour les blogs.
environment:
ASPNETCORE_URLS: "http://+:5004"
ASPNETCORE_HTTPS_PORT: ""
ASPNETCORE_ENVIRONMENT: "Production"
ports:
- "5004:5004"
# - "5005:5005" # HTTPS : activer avec le volume letsencrypt ci-dessous
depends_on:
db:
condition: service_healthy
networks:
- yavsc-internal
- yavsc-public
# volumes:
# - /etc/letsencrypt:/etc/letsencrypt:ro
volumes:
pgdata:
networks:
# Réseau interne : seuls les services Yavsc et la base s'y voient.
yavsc-internal:
internal: false
# Réseau public : exposé à l'hôte via les ports mappés.
yavsc-public:
secrets:
# appsettings-org.json vit à src/Yavsc.Org/appsettings-org.json
# (non commité). BuildKit le monte dans
# /run/secrets/yavsc_appsettings pendant le build de chaque image
# runtime via le Dockerfile multi-stage.
yavsc_appsettings:
file: ./src/Yavsc.Org/appsettings-org.json