feat: switch to adapter-static + nginx for SPA deployment #57
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-docs-app!57
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "53-adapter-static-nginx"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Changes
svelte.config.js: swap@sveltejs/adapter-nodefor@sveltejs/adapter-staticwith SPA fallback toindex.htmlpackage.json/package-lock.json: replace adapter-node dep with adapter-static (removes ~16 transitive deps)src/routes/+layout.ts: new file, setsssr = falseandprerender = falsefor pure client-side SPA modeDockerfile: replace Node.js runtime stage with nginx:alpine, serve static build on port 80 withtry_filesSPA fallbackk8s/deployment.yaml: removeenvFrom,env(server secrets/env vars), port 3000 -> 80, lower memory 128Mi -> 64Mi, faster probe timingk8s/service.yaml: port 3000 -> 80k8s/kustomization.yaml: removepal-e-auth-secrets.enc.yamlreferencek8s/pal-e-auth-secrets.enc.yaml: deleted (no longer needed)Test Plan
npm run checkpasses (0 errors, 1 pre-existing a11y warning)npm run buildpasses, adapter-static writes site tobuild/withindex.htmlfallbackReview Checklist
Related Notes
pal-e-app-- the project this work belongs toDiscovered Scope
pal-e-deploymentsoverlay atoverlays/pal-e-app/prod/still references port 3000 in kustomize patches and ingress. Needs a companion PR to update ports 3000 -> 80 and remove thepal-e-auth-secrets.enc.yamlresource.QA Review -- PR #57
Diff Analysis (9 files, +54/-295)
svelte.config.js -- Correct adapter swap.
fallback: 'index.html'enables SPA mode. Config matches mcd-tracker-app reference exactly (withstrict: true,precompress: false).src/routes/+layout.ts -- Required for adapter-static SPA mode.
ssr = falseandprerender = falsematch the mcd-tracker-app pattern. Correctly placed at root layout level.package.json / package-lock.json -- Clean swap from
@sveltejs/adapter-nodeto@sveltejs/adapter-static. Removes ~16 transitive dependencies (rollup plugins, resolve, etc.). No unrelated dependency changes.Dockerfile -- Clean replacement of Node.js runtime with nginx:alpine. Build stage unchanged. nginx config includes
try_files $uri $uri/ /index.htmlfor SPA fallback and static asset caching with 1y expiry. Matches mcd-tracker-app Dockerfile exactly.k8s/deployment.yaml -- All server env vars (
PAL_E_DOCS_API_URL,PAL_E_DOCS_API_KEY,AUTH_TRUST_HOST) andenvFromremoved. Port 3000 -> 80. Probe timings tightened (nginx starts faster than Node). Memory reduced 128Mi -> 64Mi (appropriate for nginx). Image tag line format preserved so CIsedpattern still works.k8s/service.yaml -- Port 3000 -> 80 on both
portandtargetPort.k8s/kustomization.yaml --
pal-e-auth-secrets.enc.yamlreference removed.k8s/pal-e-auth-secrets.enc.yaml -- Deleted. No longer needed since auth is client-side PKCE.
Verification
npm run check-- 0 errors (1 pre-existing a11y warning)npm run build-- passes, adapter-static writes tobuild/withindex.htmlfallbackDiscovered Scope (acknowledged)
The
pal-e-deploymentsoverlay still references port 3000 andpal-e-auth-secrets.enc.yaml. Correctly identified in PR body as needing a companion PR.VERDICT: APPROVE
Clean, focused infrastructure swap. All changes are consistent and match the proven mcd-tracker-app pattern. No secrets committed, no unnecessary file changes.
forgejo_admin referenced this pull request2026-03-27 02:17:53 +00:00
PR #57 Review
DOMAIN REVIEW
Tech stack: SvelteKit 2 (adapter-static), nginx:alpine Docker image, Kubernetes manifests (Deployment, Service, Kustomization), SOPS-encrypted secrets deletion.
SvelteKit / adapter-static:
svelte.config.js: Correctly configured withfallback: 'index.html'for SPA routing,pagesandassetsboth point tobuild/,strict: trueis good practice. This is textbook adapter-static SPA config.src/routes/+layout.ts: Setsssr = falseandprerender = false-- correct for pure client-side SPA mode. File is.ts(not.server.ts), which is required for adapter-static.+page.server.ts,+layout.server.ts, orhooks.server.tsfiles remain insrc/-- confirmed clean.package.json: adapter-node replaced with adapter-static v3.0.10. Lock file removes ~16 transitive deps (rollup plugins, resolve, commondir, etc.). Clean dependency reduction.Dockerfile (nginx:alpine):
mcd-tracker-app/Dockerfileexactly: same build stage, same nginx stage, sameprintfconfig injection, sametry_filesSPA fallback, same static asset cache headers.try_files $uri $uri/ /index.htmlis correct for SPA deep-link support.expires 1y,Cache-Control: public, immutable) is appropriate for hashed SvelteKit output.EXPOSE 80andCMD ["nginx", "-g", "daemon off;"]are correct.Kubernetes manifests:
deployment.yaml: All server env vars removed (envFrom,envblock withPAL_E_DOCS_API_URL,PAL_E_DOCS_API_KEY,AUTH_TRUST_HOST). No secrets references remain. Port correctly changed to 80. Memory reduced from 128Mi to 64Mi -- appropriate for nginx serving static files. Probe timing tightened (nginx starts faster than Node.js).service.yaml: Port 3000 -> 80 on bothportandtargetPort.kustomization.yaml:pal-e-auth-secrets.enc.yamlreference removed.pal-e-auth-secrets.enc.yaml: Deleted. SOPS-encrypted file containingAUTH_SECRET,AUTH_KEYCLOAK_ID,AUTH_KEYCLOAK_SECRET,AUTH_KEYCLOAK_ISSUER,PAL_E_DOCS_API_KEY-- all server-side auth secrets that are no longer needed after PKCE migration.Security: The deletion of server secrets is a positive security change. Client-side auth uses PKCE (no client secret). The
api-client.tscorrectly usesVITE_prefixed env vars and the public Tailscale funnel URL, with Bearer token auth from keycloak-js. No secrets leak risk.BLOCKERS
None. This is a clean infrastructure swap with no new functionality requiring test coverage. The PR is a build/deploy infrastructure change -- the application code itself is unchanged. Existing Playwright E2E tests in CI cover the app behavior, and the PR correctly notes that post-merge validation (nginx starts, SPA routing works) is needed.
NITS
docker-compose.ymlport mapping is stale (/home/ldraney/pal-e-app/docker-compose.ymlline 5): Still maps3000:3000but the container now exposes port 80. Should be"3000:80"(or"80:80") to work for local Docker Compose usage. Theenvironmentblock also still passesPAL_E_DOCS_API_URLandNODE_ENV=productionwhich are no longer consumed by the nginx container.CLAUDE.mdis completely stale (/home/ldraney/pal-e-app/CLAUDE.md): Still references adapter-node (lines 8, 29), Tailwind CSS (line 9), server-side data loading via+page.server.ts(lines 11, 26, 58-61), and server-onlyapi.ts(line 52). After this PR and PR #55, every convention listed is wrong. This will actively mislead agents working on this repo..env.examplereferences server-side vars (/home/ldraney/pal-e-app/.env.example): DocumentsPAL_E_DOCS_API_URL(noVITE_prefix, server-side) andPAL_E_DOCS_API_KEY. Neither is consumed anymore. The client-side equivalent isVITE_PAL_E_DOCS_API_URL(used inapi-client.ts).README.mdreferences.env.example(/home/ldraney/pal-e-app/README.mdline 9): Thecp .env.example .envinstruction sets a server-side var that no longer does anything.Discovered scope is well-documented: The
pal-e-deploymentsoverlay port update is correctly called out. Good practice.Note: Nits 1-4 are all documentation/config staleness from the broader adapter-node -> adapter-static + PKCE migration spanning PRs #55 and #57. They should be tracked as a follow-up issue (or folded into existing #56 "QA nits from PR #55").
SOP COMPLIANCE
53-adapter-static-nginxreferences issue #53PROCESS OBSERVATIONS
VERDICT: APPROVED
The core infrastructure change is clean, correct, and follows the established mcd-tracker-app pattern exactly. No blockers. The stale documentation files (CLAUDE.md, .env.example, README.md, docker-compose.yml) should be tracked as a follow-up issue -- they predate this PR and are cumulative debt from the #55 + #57 migration.