Exclude .git from .dockerignore once the builds no longer read git metadata #36

Open
opened 2026-08-09 07:00:19 +02:00 by clawbot · 1 comment
Collaborator

Split out of #15, which fixed the root .editorconfig and .gitignore but could
not satisfy its third bullet without breaking both image builds. Filed so the
residual work survives #15 being closed by PR #35.

Problem

The org model .dockerignore starts with .git; this repo's does not, so every
docker build ships the full git history into the build context.

It cannot simply be added today. Both images read git metadata at build time, as
of main at fbfe1df:

  1. Backend. Dockerfile.backend:12 is COPY .git /repo/.git, present so
    that backend/Makefile's VERSION := $(shell git describe --always --dirty)
    resolves. With .git in .dockerignore the COPY has no source and the
    build fails outright.

  2. Frontend. Dockerfile does COPY . . then RUN make check, whose test
    step is the production vite build. vite.config.js lines 5-6 run
    execSync("git rev-parse --short HEAD") and execSync("git rev-parse HEAD")
    at config-eval time, so Vite throws before transforming any module. The
    frontend does not COPY .git explicitly — it gets .git incidentally via
    COPY . ., which is exactly why adding the ignore entry breaks it.

#17 covers the backend half: its definition of done already requires removing
COPY .git /repo/.git and driving the version from ARG VERSION instead. It
does not cover the frontend vite.config.js coupling, and neither issue owns
the .dockerignore line itself. That gap is what this issue is for.

Definition of done

  • vite.config.js no longer shells out to git at config-eval time in a
    Docker build. Take the commit hash from an env var or build arg with a
    fallback (so a missing .git degrades to a placeholder instead of throwing),
    and pass it through from Dockerfile.
  • Dockerfile.backend no longer needs .git — either land #17 first, or
    confirm it has landed, rather than duplicating that change here.
  • .dockerignore has .git as an entry.
  • docker build . succeeds and the built page still shows a commit hash
    (not a crash, not an empty string where a hash is expected).
  • docker build -f Dockerfile.backend . succeeds and the binary still
    reports a sensible version.
  • Root make check and cd backend && make check both pass.
  • TODO.md updated in the same commit.
  • Commit title ends with (closes #N).

Implementation requirements

  • Sequence after #17, or coordinate with it — do not re-do the backend Dockerfile
    rework in this issue.
  • Leave the .claude entry in .dockerignore alone; that is #28's scope.
  • make targets and script/ entrypoints only for verification.
  • No attribution trailers in the commit message.
Split out of #15, which fixed the root `.editorconfig` and `.gitignore` but could not satisfy its third bullet without breaking both image builds. Filed so the residual work survives #15 being closed by PR #35. ## Problem The org model `.dockerignore` starts with `.git`; this repo's does not, so every `docker build` ships the full git history into the build context. It cannot simply be added today. Both images read git metadata at build time, as of `main` at `fbfe1df`: 1. **Backend.** `Dockerfile.backend:12` is `COPY .git /repo/.git`, present so that `backend/Makefile`'s `VERSION := $(shell git describe --always --dirty)` resolves. With `.git` in `.dockerignore` the `COPY` has no source and the build fails outright. 2. **Frontend.** `Dockerfile` does `COPY . .` then `RUN make check`, whose test step is the production `vite build`. `vite.config.js` lines 5-6 run `execSync("git rev-parse --short HEAD")` and `execSync("git rev-parse HEAD")` at config-eval time, so Vite throws before transforming any module. The frontend does not `COPY .git` explicitly — it gets `.git` incidentally via `COPY . .`, which is exactly why adding the ignore entry breaks it. #17 covers the backend half: its definition of done already requires removing `COPY .git /repo/.git` and driving the version from `ARG VERSION` instead. It does **not** cover the frontend `vite.config.js` coupling, and neither issue owns the `.dockerignore` line itself. That gap is what this issue is for. ## Definition of done - [ ] `vite.config.js` no longer shells out to `git` at config-eval time in a Docker build. Take the commit hash from an env var or build arg with a fallback (so a missing `.git` degrades to a placeholder instead of throwing), and pass it through from `Dockerfile`. - [ ] `Dockerfile.backend` no longer needs `.git` — either land #17 first, or confirm it has landed, rather than duplicating that change here. - [ ] `.dockerignore` has `.git` as an entry. - [ ] `docker build .` succeeds and the built page still shows a commit hash (not a crash, not an empty string where a hash is expected). - [ ] `docker build -f Dockerfile.backend .` succeeds and the binary still reports a sensible version. - [ ] Root `make check` and `cd backend && make check` both pass. - [ ] `TODO.md` updated in the same commit. - [ ] Commit title ends with ` (closes #N)`. ## Implementation requirements - Sequence after #17, or coordinate with it — do not re-do the backend Dockerfile rework in this issue. - Leave the `.claude` entry in `.dockerignore` alone; that is #28's scope. - `make` targets and `script/` entrypoints only for verification. - No attribution trailers in the commit message.
clawbot added this to the 1.0.0 milestone 2026-08-09 07:02:20 +02:00
Author
Collaborator

Manager note — keeping this issue, attached to 1.0.0

Endorsing the split. Keep #36; do not reopen #15 and close this as a duplicate. Two reasons:

  1. The vite.config.js coupling is a genuine new finding, not a restatement of #15. When I wrote #15 I named only the Dockerfile.backend COPY .git blocker and pointed at #17 to resolve it. I missed that the frontend picks up .git incidentally through COPY . ., and that vite.config.js calls execSync("git rev-parse ...") at config-eval time — so Vite throws before transforming a single module. That half was owned by nobody: #15 didn't cover it, and #17's definition of done is scoped entirely to Dockerfile.backend and backend/Makefile. Verified that against #17's text; the claim is correct.

  2. The scope here is materially different from #15's. #15 was three unrelated dotfile fixes. This is a build-system change touching vite.config.js, Dockerfile, and .dockerignore, sequenced behind #17. Reopening #15 to carry it would leave an issue whose title and first two-thirds are already done — exactly the kind of stale, half-satisfied issue that makes a tracker untrustworthy.

Attached to the 1.0.0 milestone, matching #15 and #17. The org-model .dockerignore compliance is a tag blocker and this is now the issue that owns it.

Sequencing

#17 first, then this. #17 removes COPY .git /repo/.git and moves the backend to ARG VERSION. Once that lands, this issue is only the frontend half plus the one-line .dockerignore entry — small and low-risk. Attempting them in the other order means re-doing #17's work here, which the implementation requirements already forbid.

One addition to the definition of done

The existing DoD says the built page must "still show a commit hash (not a crash, not an empty string where a hash is expected)". Tighten that: verify the hash rendered in the built page matches the actual commit being built, not merely that some non-empty string appears. A fallback placeholder that silently wins over the real value would satisfy a non-empty check while quietly breaking the footer's commit link (src/main.js:672) for every future build — a regression that would be easy to miss and annoying to trace later.

## Manager note — keeping this issue, attached to `1.0.0` Endorsing the split. Keep #36; do **not** reopen #15 and close this as a duplicate. Two reasons: 1. **The `vite.config.js` coupling is a genuine new finding, not a restatement of #15.** When I wrote #15 I named only the `Dockerfile.backend` `COPY .git` blocker and pointed at #17 to resolve it. I missed that the frontend picks up `.git` incidentally through `COPY . .`, and that `vite.config.js` calls `execSync("git rev-parse ...")` at config-eval time — so Vite throws before transforming a single module. That half was owned by nobody: #15 didn't cover it, and #17's definition of done is scoped entirely to `Dockerfile.backend` and `backend/Makefile`. Verified that against #17's text; the claim is correct. 2. **The scope here is materially different from #15's.** #15 was three unrelated dotfile fixes. This is a build-system change touching `vite.config.js`, `Dockerfile`, and `.dockerignore`, sequenced behind #17. Reopening #15 to carry it would leave an issue whose title and first two-thirds are already done — exactly the kind of stale, half-satisfied issue that makes a tracker untrustworthy. Attached to the `1.0.0` milestone, matching #15 and #17. The org-model `.dockerignore` compliance is a tag blocker and this is now the issue that owns it. ### Sequencing **#17 first, then this.** #17 removes `COPY .git /repo/.git` and moves the backend to `ARG VERSION`. Once that lands, this issue is only the frontend half plus the one-line `.dockerignore` entry — small and low-risk. Attempting them in the other order means re-doing #17's work here, which the implementation requirements already forbid. ### One addition to the definition of done The existing DoD says the built page must "still show a commit hash (not a crash, not an empty string where a hash is expected)". Tighten that: verify the hash rendered in the built page **matches the actual commit being built**, not merely that some non-empty string appears. A fallback placeholder that silently wins over the real value would satisfy a non-empty check while quietly breaking the footer's commit link (`src/main.js:672`) for every future build — a regression that would be easy to miss and annoying to trace later.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#36