fix(build): Containerfile builds again — relative module imports, all four pages and shared assets in the image
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Task 01 — Fix the build: relative imports, tag removal, full stage-1 asset coverage
|
||||
|
||||
**Phase:** `23_containerfile_build` · **Source:** `TODO.md` L6 —
|
||||
*"Fix Containerfile build not working"*
|
||||
|
||||
## Objective
|
||||
Make `podman build -f Containerfile .` succeed and ship the **complete**
|
||||
frontend in the image: all four pages, all four bundled page modules,
|
||||
the classic `markdown.js`, and the minified `styles.css` — with
|
||||
`header.js` evaluated exactly once per page.
|
||||
|
||||
## Work
|
||||
1. **Reproduce the failure** and record it in
|
||||
`.agent/reports/23_containerfile_build/` (log excerpt):
|
||||
- fast: `npx -y esbuild@0.25.5` on a copy of `frontend/` → the
|
||||
`Could not resolve "/assets/header.js"` error (root cause, already
|
||||
reproduced during conversion);
|
||||
- authoritative: `podman build -f Containerfile .` → stage 1 fails
|
||||
at the same line.
|
||||
2. **`frontend/assets/{app,sources,document,login}.js`** — change the
|
||||
header import from absolute URL to relative (one line each; the
|
||||
specifiers are currently `from "/assets/header.js"`):
|
||||
```js
|
||||
import { … } from "./header.js";
|
||||
```
|
||||
(owner-confirmed A4 — relative over esbuild alias; dev-server
|
||||
behavior is unchanged since the files are side-by-side and the
|
||||
module URL resolves to the same file.)
|
||||
3. **Remove the four redundant direct `header.js` tags** (owner-confirmed
|
||||
A4-2 — the single-evaluation design from `00_phase.md`):
|
||||
- `frontend/index.html` (~line 119) —
|
||||
`<script type="module" src="/assets/header.js"></script>`;
|
||||
- `frontend/sources.html` (~line 125), `frontend/document.html`
|
||||
(~line 80), `frontend/login.html` (~line 67) — same tag.
|
||||
- Update the surrounding HTML comments that describe the
|
||||
header-before-page-script load order (e.g. index.html ~lines
|
||||
115–119): the order is now guaranteed by the page script's own
|
||||
`import` (hoisted, evaluated before the page script body calls
|
||||
`initSharedHeader()`).
|
||||
4. **`Containerfile` stage 1** — cover the whole app (keep the pinned
|
||||
`esbuild@0.25.5` and the existing flags):
|
||||
```dockerfile
|
||||
RUN mkdir -p /out/assets \
|
||||
&& esbuild ./assets/app.js --bundle --minify --format=esm --target=es2022 --outfile=/out/assets/app.js \
|
||||
&& esbuild ./assets/sources.js --bundle --minify --format=esm --target=es2022 --outfile=/out/assets/sources.js \
|
||||
&& esbuild ./assets/document.js --bundle --minify --format=esm --target=es2022 --outfile=/out/assets/document.js \
|
||||
&& esbuild ./assets/login.js --bundle --minify --format=esm --target=es2022 --outfile=/out/assets/login.js \
|
||||
&& esbuild ./assets/markdown.js --minify --outfile=/out/assets/markdown.js \
|
||||
&& esbuild ./assets/styles.css --minify --outfile=/out/assets/styles.css \
|
||||
&& cp ./index.html ./sources.html ./document.html ./login.html /out/
|
||||
```
|
||||
(`markdown.js` is a classic script — minify only, **no** `--bundle`;
|
||||
it exposes globals used by the pages.)
|
||||
5. **Verify locally (no podman):** with esbuild 0.25.5, all four module
|
||||
bundles + the markdown minify succeed on the real `frontend/` (not a
|
||||
copy — the copy was only for the diagnosis).
|
||||
6. **`podman build -f Containerfile .`** → green.
|
||||
7. **Image smoke test** (results + log excerpt into the report dir):
|
||||
- throwaway Postgres 17 + pgvector (`podman compose up -d db` and
|
||||
point the container at it, or a one-off container with the same
|
||||
env as `compose.yaml`);
|
||||
- run the built image (migrations run via the entrypoint);
|
||||
- `GET /`, `/sources.html`, `/document.html`, `/login.html` → 200;
|
||||
- `GET /assets/app.js` → 200, minified (single-line-ish), and
|
||||
contains the header code (e.g. the `clearChatStorage` function
|
||||
body); `GET /assets/markdown.js`, `/styles.css`, the other three
|
||||
page modules → 200;
|
||||
- No CDN rule: none of the four served pages contain an `http(s)://`
|
||||
`src`/`href` asset reference.
|
||||
- Teardown the throwaway containers when done.
|
||||
8. **Dev-server regression check** (the tag removal touches dev page
|
||||
load — confirm boot order still holds): `uv run uvicorn
|
||||
app.main:app --reload`, load all four pages, check the sign-out
|
||||
binding exists exactly once (DevTools: no duplicate listener — one
|
||||
`POST /api/logout` per click) and `initSharedHeader()` ran. (The
|
||||
isolated E2E regressions run in task 02.)
|
||||
|
||||
## Testing & Quality
|
||||
- Steps 5–8 above; `uv run ruff check . && uv run pyright` clean
|
||||
(no Python changes, but keep the gate green).
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] The recorded build failure is fixed at the root cause (relative
|
||||
imports) — not masked by an alias/patch.
|
||||
- [ ] All four direct `header.js` tags removed + comments updated; the
|
||||
page scripts' `import "./header.js"` is the only header load.
|
||||
- [ ] Stage 1 produces: 4 HTML pages, 4 bundled modules, minified
|
||||
`markdown.js`, minified `styles.css`.
|
||||
- [ ] `podman build` green; image smoke all-200 + No CDN + single
|
||||
header evaluation; dev-server boot unchanged (step 8).
|
||||
- [ ] Log/screenshot evidence in `.agent/reports/23_containerfile_build/`.
|
||||
Reference in New Issue
Block a user