From a85995fb6e7875e7f233a3db3b3d6631613e0306 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Sat, 20 Jun 2026 20:01:53 -0600 Subject: [PATCH] fix(docker): make compose stack start cold (gh_token secret + correct healthcheck) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I1: the app service builds from the Dockerfile, which pulls the private batch-job-api from GitHub Packages via a BuildKit secret (id=gh_token). docker-compose.yml declared no secret, so `docker compose up` failed the build cold with a missing /run/secrets/gh_token. Wire the secret from the GITHUB_TOKEN env var and pass GITHUB_ACTOR as a build arg. I2: both the Dockerfile HEALTHCHECK and the compose healthcheck probed /actuator/health, which is 503 until a plugin is loaded — a fresh container would loop unhealthy/restart forever. Probe /jobs/plugins (200 once serving, and public), matching CI and process-compose readiness. Document the GITHUB_TOKEN requirement in RUNNING_LOCALLY.md. --- RUNNING_LOCALLY.md | 5 +++++ docker-compose.yml | 16 +++++++++++++++- fr-batch-service/Dockerfile | 6 +++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/RUNNING_LOCALLY.md b/RUNNING_LOCALLY.md index 375330b..05ea94f 100644 --- a/RUNNING_LOCALLY.md +++ b/RUNNING_LOCALLY.md @@ -392,8 +392,13 @@ Open the dashboard at http://localhost:5173 — you should see all four jobs lis A root-level `docker-compose.yml` runs MySQL, the Spring Boot app (built from the Dockerfile), Prometheus, and Grafana together. It targets the `docker` profile, not `local`. +The app image builds from source and pulls the private `batch-job-api` from GitHub Packages, so the build needs a token. Export `GITHUB_TOKEN` (a PAT with `read:packages`) — it is passed to the build as a BuildKit secret and never lands in an image layer: + ```bash +export GITHUB_TOKEN= DB_PASSWORD=yourpassword docker compose up -d ``` +If your GitHub username matters for package auth, also `export GITHUB_ACTOR=` (defaults to `x-access-token`). + This is useful for a production-like smoke test, but not the recommended path for day-to-day development because it rebuilds the app image on every change. diff --git a/docker-compose.yml b/docker-compose.yml index a1dd1f3..6ef7c16 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,13 @@ services: build: context: ./fr-batch-service dockerfile: Dockerfile + # The Dockerfile pulls the private batch-job-api from GitHub Packages, so the + # build needs a token. Export GITHUB_TOKEN (a PAT with read:packages) before + # `docker compose up`; GITHUB_ACTOR defaults to x-access-token if unset. + args: + GITHUB_ACTOR: ${GITHUB_ACTOR:-x-access-token} + secrets: + - gh_token ports: - "8080:8080" environment: @@ -33,7 +40,9 @@ services: mysql: condition: service_healthy healthcheck: - test: ["CMD", "wget", "-qO-", "http://localhost:8080/api/batch-service/actuator/health"] + # Not /actuator/health: it is 503 until a plugin is loaded (endless restart + # loop on a fresh stack). /jobs/plugins is 200 once the app serves. + test: ["CMD", "wget", "-qO-", "http://localhost:8080/api/batch-service/jobs/plugins"] interval: 30s timeout: 5s retries: 3 @@ -78,3 +87,8 @@ volumes: plugin-jars: prometheus-data: grafana-data: + +secrets: + # Sourced from the GITHUB_TOKEN env var at build time (BuildKit secret). + gh_token: + environment: GITHUB_TOKEN diff --git a/fr-batch-service/Dockerfile b/fr-batch-service/Dockerfile index f3f5e8a..a4fd181 100644 --- a/fr-batch-service/Dockerfile +++ b/fr-batch-service/Dockerfile @@ -28,8 +28,12 @@ RUN addgroup -S appgroup && adduser -S appuser -G appgroup RUN apk add --no-cache wget WORKDIR /app COPY --from=build /build/target/*.jar app.jar +# Probe the plugin-listing endpoint, not /actuator/health: the aggregate health +# is DOWN (503) until at least one plugin is loaded, which would put a fresh +# container in an endless unhealthy/restart loop. /jobs/plugins returns 200 as +# soon as the app serves — the same readiness signal used by CI and process-compose. HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ - CMD wget -qO- http://localhost:8080/api/batch-service/actuator/health || exit 1 + CMD wget -qO- http://localhost:8080/api/batch-service/jobs/plugins || exit 1 USER appuser EXPOSE 8080 ENTRYPOINT ["java", "-Xmx512m", "-XX:MaxMetaspaceSize=256m", "-jar", "app.jar"]