From 2780bce4fd1c07164aa52bd079fe7a8c1a51510a Mon Sep 17 00:00:00 2001 From: Edwin van den Houdt Date: Wed, 3 Jun 2026 13:46:17 +0200 Subject: [PATCH] feat(infra): containerize BFF + compose-up smoke (refs #29) Add a multi-stage Dockerfile for the BFF (.NET 10 sdk -> aspnet runtime, curl for the healthcheck) and infra/docker-compose.yml running it with a /health healthcheck. `docker compose up --wait` gates on the container reporting healthy, which is the compose-up smoke test. Document the path in the README. Verified: image builds; `docker compose up -d --build --wait` reports the container Healthy; host curl http://localhost:8080/health -> 200 Healthy. Co-Authored-By: Claude Opus 4.8 --- README.md | 9 +++++++++ infra/docker-compose.yml | 19 +++++++++++++++++++ services/bff/.dockerignore | 3 +++ services/bff/Dockerfile | 30 ++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 infra/docker-compose.yml create mode 100644 services/bff/.dockerignore create mode 100644 services/bff/Dockerfile diff --git a/README.md b/README.md index 98873fb..ae79704 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,15 @@ docker compose -f infra/docker-compose.yml up -d Health checks should be green within ~3 minutes on a developer machine. If something fails, see [docs/runbooks/local-startup.md](docs/runbooks/local-startup.md). +> **Wired today (Iteration 0):** only the placeholder BFF is in `infra/docker-compose.yml` so far. Bring it up and smoke-test its health endpoint: +> +> ```bash +> docker compose -f infra/docker-compose.yml up -d --build --wait +> curl http://localhost:8080/health # -> Healthy +> ``` +> +> `--wait` exits non-zero unless the container reports healthy, so this doubles as the compose-up smoke test. The remaining services and the URLs below land in later slices. + **Default URLs** | Service | URL | diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml new file mode 100644 index 0000000..1c5e980 --- /dev/null +++ b/infra/docker-compose.yml @@ -0,0 +1,19 @@ +# Local development stack. Grows service-by-service with each slice. +# S-00-b: the placeholder BFF with a /health check. +# +# docker compose -f infra/docker-compose.yml up -d --build --wait +# curl http://localhost:8080/health # -> Healthy +services: + bff: + build: + context: ../services/bff + dockerfile: Dockerfile + image: register-referentie/bff:dev + ports: + - "8080:8080" + healthcheck: + test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"] + interval: 5s + timeout: 3s + retries: 5 + start_period: 10s diff --git a/services/bff/.dockerignore b/services/bff/.dockerignore new file mode 100644 index 0000000..39d8eb6 --- /dev/null +++ b/services/bff/.dockerignore @@ -0,0 +1,3 @@ +**/bin +**/obj +**/*.user diff --git a/services/bff/Dockerfile b/services/bff/Dockerfile new file mode 100644 index 0000000..27acf91 --- /dev/null +++ b/services/bff/Dockerfile @@ -0,0 +1,30 @@ +# Multi-stage build for the placeholder BFF (.NET 10). +# Build context is services/bff (see infra/docker-compose.yml). +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +WORKDIR /src + +# Restore first (cached unless the csproj changes). +COPY Bff.Api/Bff.Api.csproj Bff.Api/ +RUN dotnet restore Bff.Api/Bff.Api.csproj + +# Then build + publish. +COPY Bff.Api/ Bff.Api/ +RUN dotnet publish Bff.Api/Bff.Api.csproj -c Release -o /app/publish /p:UseAppHost=false + +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime +WORKDIR /app + +# curl is used by the container HEALTHCHECK / compose healthcheck. +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=build /app/publish . + +ENV ASPNETCORE_URLS=http://+:8080 +EXPOSE 8080 + +HEALTHCHECK --interval=5s --timeout=3s --start-period=10s --retries=5 \ + CMD curl -fsS http://localhost:8080/health || exit 1 + +ENTRYPOINT ["dotnet", "Bff.Api.dll"] -- 2.49.1