# Phase 23 — Containerfile: Build the Whole App Image Again **Source:** `TODO.md` L6 — *"Fix Containerfile build not working"* **Story:** `.agent/user_stories/containerfile-build.md` (created by task 02) **Context:** `Containerfile` (3 stages: node:22-alpine + esbuild 0.25.5 frontend bundle → uv/python deps → slim runtime serving `/app/static`); `frontend/` (4 pages: `index.html`, `sources.html`, `document.html`, `login.html`; assets: `styles.css`, `markdown.js` (classic script), `header.js`/`app.js`/`sources.js`/`document.js`/ `login.js` (ES modules)); `scripts/entrypoint.sh`. ## Verified diagnosis (2026-08-24, this conversion — not a guess) 1. **Root cause of the build failure:** phase 19 switched the page scripts to `import … from "/assets/header.js"` (an absolute URL). esbuild resolves that as the *filesystem* path `/assets/header.js` and the stage-1 bundle dies: `✘ [ERROR] Could not resolve "/assets/header.js"` (reproduced with esbuild **0.25.5**, the exact pinned version, on a copy of `frontend/`). 2. **Secondary gap (image would be broken even if it built):** stage 1 bundles only `app.js` + `sources.js` and copies only `index.html` + `sources.html`. Missing from the image: `document.html` + `login.html` (phases 10/16), `document.js` + `login.js`, and `markdown.js` (classic script loaded by `index.html` + `document.html`). 3. **Verified fix:** with relative imports (`from "./header.js"`) all four page scripts bundle cleanly with esbuild 0.25.5. 4. **Latent double-evaluation trap:** all four HTML pages also load `