Skip to content

Deep-test fixes: ro cert-mount crash, wasm variant repair, duplicate Cache-Control, README accuracy - #6

Merged
mrhegemon merged 1 commit into
mainfrom
chore/deep-test-fixes
Jun 10, 2026
Merged

mrhegemon merged 1 commit into
mainfrom
chore/deep-test-fixes

Conversation

@mrhegemon

Copy link
Copy Markdown
Member

QA deep-test of the published image (ghcr.io/companionintelligence/ci-static-containter-builder:latest) and both build flows. All issues below were reproduced before fixing and re-verified after.

Bugs fixed

  1. Read-only cert mount crashed the container (entrypoint). The README's documented Let's Encrypt flow (-v …fullchain.pem:/etc/nginx/ssl/server.crt:ro) exited with chmod: Read-only file system because set -e + unconditional chmod. chmod now lives in the branches that write files and is best-effort for pre-existing certs. Verified: :ro mount now serves 200 over HTTPS.
  2. Silent fallback when only one of SSL_CERT/SSL_KEY is set — now logs a WARNING before generating a self-signed cert.
  3. Duplicate Cache-Control headers (nginx.conf) — expires + add_header Cache-Control sent two conflicting values on every asset (max-age=31536000 + public, immutable) and HTML response. Collapsed to one explicit header per location.
  4. Dockerfile.wasm no longer built — Fermyon's install.sh now requires git (template install step). Added git to the spin-setup stage.
  5. Spin manifest was invalid + digest corrupted (spin/spin.toml) — [component.fileserver.files] table is rejected by Spin v2 (files must be an array), and the pinned sha256 for spin_static_fs.wasm v0.3.0 didn't match the released artifact (verified independently via download + shasum). Runtime previously crash-looped.
  6. WASM image was not self-contained — the pre-fetched component cache (/root/.cache/spin) was never copied into the runtime stages, so every boot re-downloaded the fileserver from GitHub (and failed offline). wasm-scratch additionally COPY'd a nonexistent /root/.spin/cache, which failed the build. Both targets now build; spin-server verified serving with --network none.

Docs corrected

  • README/Dockerfile claimed nginx:1.27-alpine / ~25 MB; the base is Debian nginx:1.27 (~70 MB). Table, diagram, and comments updated.
  • Added a "Use the published image" quick-start documenting the public multi-arch GHCR image and the FROM … overlay pattern.
  • Documented that STATIC_FILES_PATH must point inside the Docker build context.
  • Realistic wasm image sizes (~300 MB spin-server, ~5 MB scratch measured).

Verification (published image + worktree builds, ports 18190-18199)

  • 80→443 redirect: 301, Location: https://…
  • HTTPS: 200 over HTTP/2; default landing page renders; /health returns healthy
  • Cert auto-gen: CN=localhost, SAN localhost/*.localhost/127.0.0.1; SSL_DOMAIN=test.local → CN/SAN test.local; SSL_CERT+SSL_KEY env injection serves the provided cert
  • Restart: cert reused ("Using existing SSL certificate"), serves 200
  • gzip on text >1 KB with Vary: Accept-Encoding; SPA fallback serves index for deep routes; all 6 security headers present on every response
  • Functional packaging test: derived image with custom index.html built via --build-arg STATIC_FILES_PATH and served over HTTPS

🤖 Generated with Claude Code

… README accuracy

Deep-test fixes from QA of the published image and build flows:

- docker-entrypoint.sh: unconditional `chmod` crashed the container when
  certs were bind-mounted read-only (the exact flow the README documents
  for Let's Encrypt). chmod now happens only where files are written, and
  is best-effort for pre-existing (possibly :ro) certs. Also warn when
  only one of SSL_CERT/SSL_KEY is set instead of silently ignoring it.
- nginx.conf: `expires` + `add_header Cache-Control` emitted two
  conflicting Cache-Control headers on every asset/HTML response; collapse
  to a single explicit Cache-Control per location.
- Dockerfile.wasm: spin-server build broke (Fermyon install.sh now needs
  git); component cache was never copied into the runtime stages, so the
  image fetched the fileserver from the internet on every boot (and
  wasm-scratch COPY pointed at a nonexistent /root/.spin/cache).
- spin/spin.toml: invalid Spin v2 manifest ([component.fileserver.files]
  table instead of a `files` array) and a corrupted component digest;
  runtime failed to parse/verify. Verified serving with --network none.
- README/Dockerfile comments: base image is Debian nginx:1.27 (not
  alpine, not ~25 MB); document the public GHCR multi-arch image and the
  build-context constraint on STATIC_FILES_PATH.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@mrhegemon
mrhegemon merged commit 813f8db into main Jun 10, 2026
1 check passed
@mrhegemon
mrhegemon deleted the chore/deep-test-fixes branch September 10, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant