From da6d64f95ce369f50de4f2c7f23c68676832341c Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Thu, 6 Aug 2026 15:46:30 +0100 Subject: [PATCH] fix: give the scratch server image a /tmp for the vulnerability database The runtime stage is FROM scratch, which has no /tmp, so vulnsched died at startup with "temp dir: stat /tmp: no such file or directory" and no scan ever ran. Nothing in the server wrote to a temporary directory before the trivy-db puller, which is why this only appeared now. scratch cannot mkdir its own, so the directory is staged in the builder at 1777 and copied in. Also corrects CLAUDE.md, which described this image as Alpine; the time/tzdata import it justifies is if anything more load-bearing on scratch. --- CLAUDE.md | 8 +++++++- server/Dockerfile | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index c9db44e..a799d5d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -147,7 +147,7 @@ with `"schedule"` as the actor, so there is no second dispatch path and the run detail page needed no changes. `main.go` imports `_ "time/tzdata"`, and it is load-bearing: `server/Dockerfile` -builds on Alpine, which ships no zone database, so without it +runs on `scratch`, which ships no zone database, so without it `time.LoadLocation("Europe/London")` fails and every schedule silently falls back to UTC — an hour wrong for half the year, in the direction nobody notices until a maintenance window lands in business hours. It works on a developer @@ -350,6 +350,12 @@ is where risk goes to be forgotten. An unsupported distribution reports unknown is the same lie as a silently stale database, which is why `vulndb_meta.pulled_at` is on screen rather than only in a log. +**`server/Dockerfile`'s runtime stage is `scratch`, so it carries an explicitly +copied `/tmp`.** The scheduler unpacks the database to a temporary directory, +and a scratch image has none — the failure is `vulnsched: temp dir: stat /tmp: +no such file or directory`, logged once at boot while every other subsystem +runs normally, so the only symptom is a fleet that never reports a finding. + Two environment variables: `VANTAGE_TRIVY_DB_REF` mirrors the artifact for air-gapped installs, and `VANTAGE_VULNDB_DISABLED` switches the puller and scheduler off entirely. diff --git a/server/Dockerfile b/server/Dockerfile index f4a698c..44714a4 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -18,10 +18,19 @@ ARG VERSION=dev RUN cd server && CGO_ENABLED=0 GOOS=linux go build \ -ldflags="-s -w -X main.Version=${VERSION}" -o /vantage-server ./cmd +# Staged so the scratch image below can have a /tmp. It cannot mkdir one +# itself — scratch has no shell — and os.MkdirTemp fails outright without it. +RUN mkdir -p /staging/tmp && chmod 1777 /staging/tmp + # Runtime stage FROM scratch COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ + +# vulndb unpacks the ~50MB trivy-db here. Without it the scheduler stops at +# "temp dir: stat /tmp: no such file or directory" and no scanning happens, +# while everything else in the process runs perfectly well. +COPY --from=builder /staging/tmp /tmp COPY --from=builder /vantage-server /vantage-server COPY default_steps/ /opt/default-steps/