From e48cfe78377004bff7d5af9f20e5094ce50cb837 Mon Sep 17 00:00:00 2001 From: rancur <235745911+rancur@users.noreply.github.com> Date: Sun, 9 Aug 2026 14:22:23 -0700 Subject: [PATCH] fix: WaxFlow could not be built from a fresh clone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sync-web/public/ was never committed, but sync-web/Dockerfile COPYs it out of the builder stage, so a clean checkout failed with: failed to compute cache key: failed to calculate checksum of ref ... /app/public Nobody could build WaxFlow from a fresh clone. It only worked for people whose working copy already had the directory, which is why it went unnoticed — CI built from a clean checkout for the first time in 2.12.0 and the web image failed while api and worker succeeded. Verified by cloning the repo fresh: no sync-web/public. Tracks public/.gitkeep and adds `RUN mkdir -p /app/public` so the COPY cannot fail even when the directory is missing from the build context. Also documents why the web image is portable despite taking NEXT_PUBLIC_API_URL as a build arg: the frontend calls a relative /api and next.config.js rewrites it server-side from INTERNAL_API_URL at RUNTIME, so nothing user-specific is baked in. That is what lets one published image serve every install. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01HmUiLHPmKoz215WAWV5eHe --- CHANGELOG.md | 22 ++++++++++++++++++++++ VERSION | 2 +- sync-web/Dockerfile | 8 ++++++++ sync-web/public/.gitkeep | 9 +++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 sync-web/public/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md index 502c34e..2064dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## 2.12.2 — fix: WaxFlow could not be built from a fresh clone + +`sync-web/public/` was never committed, but `sync-web/Dockerfile` COPYs it out of +the builder stage. So a clean checkout failed: + + failed to compute cache key: failed to calculate checksum of ref ... /app/public + +**Nobody could build WaxFlow from a fresh clone.** It only worked for people whose +working copy already happened to have the directory — which is why it went +unnoticed until CI built from a clean checkout for the first time and the web +image failed while api and worker succeeded. + +Fixed by tracking `sync-web/public/.gitkeep` and adding `RUN mkdir -p /app/public` +so the COPY cannot fail even if the directory is absent from the build context. + +Also documented, because it looked alarming during review: `NEXT_PUBLIC_API_URL` +is a build arg, but the frontend calls a RELATIVE `/api` and `next.config.js` +rewrites it server-side from `INTERNAL_API_URL` at RUNTIME. Nothing user-specific +is baked into the web image, which is what lets one published image serve every +install. + + ## 2.12.1 — "Update Now" actually requests an update `POST /api/admin/update` wrote the literal string `requested at ` into diff --git a/VERSION b/VERSION index 3cf561c..371a952 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.12.1 +2.12.2 diff --git a/sync-web/Dockerfile b/sync-web/Dockerfile index 0e75c1a..9ea6937 100644 --- a/sync-web/Dockerfile +++ b/sync-web/Dockerfile @@ -3,6 +3,14 @@ WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . +# Belt and braces: public/ is tracked (see public/.gitkeep), but the COPY in the +# runner stage hard-fails if it is ever missing, which is how fresh-clone builds +# broke. Guarantee it exists rather than depending on the build context. +RUN mkdir -p /app/public + +# NOTE: the frontend calls a RELATIVE /api and next.config.js rewrites it +# server-side using INTERNAL_API_URL at RUNTIME, so nothing user-specific is +# baked in here. That is what makes one published image work for every install. ARG NEXT_PUBLIC_API_URL=http://localhost:8402 ARG INTERNAL_API_URL=http://sync-api:8402 ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL diff --git a/sync-web/public/.gitkeep b/sync-web/public/.gitkeep new file mode 100644 index 0000000..92b5230 --- /dev/null +++ b/sync-web/public/.gitkeep @@ -0,0 +1,9 @@ +Next.js expects a public/ directory and sync-web/Dockerfile COPYs it out of the +builder stage. It was never committed, so `docker compose up -d --build` from a +fresh clone failed with: + + failed to compute cache key: failed to calculate checksum of ref ... /app/public + +i.e. nobody could build WaxFlow from a clean checkout. It only worked for people +whose working copy already had the directory. Keep this file so the directory +always exists.