Publish Web/PWA Docker image #247

Closed
opened 2026-06-03 09:49:38 +00:00 by steve · 0 comments
Owner

Add a Forgejo publishing path for the installable Web/PWA host as a Docker Hub
image.

Problem

The Web/PWA package can be built as static content, but the repo does not yet
publish a deployable container image for hosting that build. Deployments need a
repeatable image with the same cross-origin isolation headers required by the
browser-local SQLite runtime.

Goal

Publish lapisnotes/web to Docker Hub with both a short commit tag and
latest, using a hardened static-content runtime.

Scope

  • Add a Web/PWA Dockerfile and static server config under docker/web/.
  • Add a Forgejo workflow that builds and pushes the image on main pushes and
    manual dispatch.
  • Document the image runtime, tags, required secrets, and host headers in the
    web and release-management specs.

Non-goals

  • Do not change Web/PWA app behavior or public APIs.
  • Do not add Docker Hub repository provisioning.
  • Do not publish images from arbitrary feature branches.

Acceptance Criteria

  • docker/web/Dockerfile builds @lapis-notes/web from the repo root and
    produces a distroless, nonroot Caddy runtime listening on port 8080.
  • The runtime serves the built PWA with SPA fallback for app routes, 404s for
    missing built assets, required COOP/COEP headers, and conservative cache and
    hardening headers.
  • .forgejo/workflows/publish-web.yml pushes lapisnotes/web:${GITHUB_SHA:0:12}
    and lapisnotes/web:latest to Docker Hub for main and manual runs, using
    DOCKERHUB_USERNAME and DOCKERHUB_TOKEN.
  • Relevant specs document the new image, workflow, tags, port, and secrets.

Implementation Notes

  • Use the existing .forgejo/workflows/publish-lapis-ci.yml buildx pattern for
    Docker checks, QEMU/binfmt, builder setup, and multi-arch push.
  • Use caddy:2.11.3-alpine as the Caddy source stage and
    gcr.io/distroless/static-debian12:nonroot for the runtime.
  • Pass LAPIS_BUILD_COMMIT through the Docker build so the app build records the
    source commit.

Suggested Files or Specs To Inspect

  • spec/src/20-packages/web/index.md
  • packages/web/spec.md
  • spec/src/80-maintenance/release-management.md
  • .forgejo/workflows/publish-lapis-ci.yml
  • packages/web/package.json

Validation Commands

  • pnpm build:web
  • docker buildx build --platform linux/amd64 --file docker/web/Dockerfile --build-arg LAPIS_BUILD_COMMIT=<sha> --tag lapisnotes/web:test --load .
  • docker run --rm --read-only --cap-drop=ALL --security-opt no-new-privileges -p 8080:8080 lapisnotes/web:test
  • curl -I http://localhost:8080/
  • curl -I 'http://localhost:8080/open?url=test'
  • curl -I http://localhost:8080/sw.js
  • curl -I http://localhost:8080/assets/missing.js
  • pnpm check:all
  • make spec-lint
  • mdbook build spec

Follow-up Tasks

Implementation Summary

Added the Web/PWA Docker image definition, distroless Caddy runtime config, Docker Hub publish workflow, and matching web/release specs. Validated pnpm build:web, pnpm check:all, make spec-lint, and mdbook build spec; local Docker image build/run checks were blocked because no Docker daemon was available.

Add a Forgejo publishing path for the installable Web/PWA host as a Docker Hub image. ## Problem The Web/PWA package can be built as static content, but the repo does not yet publish a deployable container image for hosting that build. Deployments need a repeatable image with the same cross-origin isolation headers required by the browser-local SQLite runtime. ## Goal Publish `lapisnotes/web` to Docker Hub with both a short commit tag and `latest`, using a hardened static-content runtime. ## Scope - Add a Web/PWA Dockerfile and static server config under `docker/web/`. - Add a Forgejo workflow that builds and pushes the image on `main` pushes and manual dispatch. - Document the image runtime, tags, required secrets, and host headers in the web and release-management specs. ## Non-goals - Do not change Web/PWA app behavior or public APIs. - Do not add Docker Hub repository provisioning. - Do not publish images from arbitrary feature branches. ## Acceptance Criteria - `docker/web/Dockerfile` builds `@lapis-notes/web` from the repo root and produces a distroless, nonroot Caddy runtime listening on port `8080`. - The runtime serves the built PWA with SPA fallback for app routes, 404s for missing built assets, required COOP/COEP headers, and conservative cache and hardening headers. - `.forgejo/workflows/publish-web.yml` pushes `lapisnotes/web:${GITHUB_SHA:0:12}` and `lapisnotes/web:latest` to Docker Hub for `main` and manual runs, using `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN`. - Relevant specs document the new image, workflow, tags, port, and secrets. ## Implementation Notes - Use the existing `.forgejo/workflows/publish-lapis-ci.yml` buildx pattern for Docker checks, QEMU/binfmt, builder setup, and multi-arch push. - Use `caddy:2.11.3-alpine` as the Caddy source stage and `gcr.io/distroless/static-debian12:nonroot` for the runtime. - Pass `LAPIS_BUILD_COMMIT` through the Docker build so the app build records the source commit. ## Suggested Files or Specs To Inspect - `spec/src/20-packages/web/index.md` - `packages/web/spec.md` - `spec/src/80-maintenance/release-management.md` - `.forgejo/workflows/publish-lapis-ci.yml` - `packages/web/package.json` ## Validation Commands - `pnpm build:web` - `docker buildx build --platform linux/amd64 --file docker/web/Dockerfile --build-arg LAPIS_BUILD_COMMIT=<sha> --tag lapisnotes/web:test --load .` - `docker run --rm --read-only --cap-drop=ALL --security-opt no-new-privileges -p 8080:8080 lapisnotes/web:test` - `curl -I http://localhost:8080/` - `curl -I 'http://localhost:8080/open?url=test'` - `curl -I http://localhost:8080/sw.js` - `curl -I http://localhost:8080/assets/missing.js` - `pnpm check:all` - `make spec-lint` - `mdbook build spec` ## Related Issues ## Follow-up Tasks ## Implementation Summary Added the Web/PWA Docker image definition, distroless Caddy runtime config, Docker Hub publish workflow, and matching web/release specs. Validated pnpm build:web, pnpm check:all, make spec-lint, and mdbook build spec; local Docker image build/run checks were blocked because no Docker daemon was available. <!-- backlog:task_id=TASK-WEB-PWA-DOCKER-IMAGE source_spec=spec/src/20-packages/web/index.md -->
steve 2026-06-03 09:49:38 +00:00
steve referenced this issue from a commit 2026-06-03 10:13:12 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lapis-notes/lapis#247
No description provided.