feat(deploy): containerize the SaaS backend — Dockerfile + compose (slice 9, stacked on #221)#222
Merged
Merged
Conversation
The #1 gap between built capability and real value: the Node backend wasn't deployable — the existing Dockerfile only serves the static client via nginx. Undeployed code has no value; this makes the full SaaS runnable. - Dockerfile.server: Node backend that runs the API AND serves the static client from one origin (satisfies the client's default-src 'self' CSP). Prod deps only (npm ci --omit=dev), non-root (USER node), /data volume for the DB, HEALTHCHECK on /api/health. - docker-compose.yml: one-command full stack. SCOPEWEAVE_JWT_SECRET is REQUIRED (compose fails fast without it) — no insecure default in prod. - .dockerignore: keeps node_modules/tests/docs out of the image. - docs/deploy.md: env vars, data/scale path (SQLite→Postgres for multi-instance), TLS/proxy, k8s notes. Verified with podman: image builds; container boots (node:sqlite works in node:22-alpine); GET /api/health → {ok:true}; signup writes DB → JWT; static client 200 (index/app.js/analytics.js); data.db blocked 404. Note: unrelated to code — the org's `trivy-fs` check currently fails repo-wide (also on unrelated PRs like #213); local trivy (all scanners) + npm audit are clean. That's a CI/trivy-version config issue for the maintainer. Stacked on #221. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LMoqYsUY6usjNMBjvxCbU
This was referenced Jul 5, 2026
Merged
…ies) Addresses the github-advanced-security review on this PR: node:22-alpine is now pinned to its sha256 digest (tag kept as a comment for humans). Verified: podman build succeeds with the pinned ref; the container boots and /api/health returns ok. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LMoqYsUY6usjNMBjvxCbU
Contributor
Author
|
Addressed the Scorecard Pinned-Dependencies finding: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SaaS pivot — slice 9 of N (stacked on #221)
The gap between "built" and "valuable": the backend wasn't deployable. The existing Dockerfile only serves the static client via nginx; the Node backend (auth/cloud/billing) never ran. This makes the full SaaS runnable with one command.
Dockerfile.server— Node backend that runs the API and serves the static client from one origin (so the client'sdefault-src 'self'CSP allows the API). Prod deps only (npm ci --omit=dev), non-root (USER node),/datavolume for the DB,HEALTHCHECKon/api/health.docker-compose.yml— one-command full stack;SCOPEWEAVE_JWT_SECRETis required (fails fast without it — no insecure default in prod)..dockerignore— keepsnode_modules/tests/docs out of the image.docs/deploy.md— env vars, data/scale path (SQLite → Postgres for multi-instance), TLS/proxy, k8s notes.Verified (podman)
Image builds; container boots (
node:sqliteworks innode:22-alpine);GET /api/health→{ok:true}; signup writes the DB and returns a JWT; static client200(index/app.js/analytics.js);data.dbblocked404.Heads-up (not this PR's code)
The org's
trivy-fscheck fails repo-wide — it also fails on unrelated PRs (e.g. #213, a UI-only change). Local trivy (vuln+secret+misconfig) andnpm auditare clean, andhonois zero-dependency. This is a CI/trivy-version config issue for the maintainer, not a real finding.🤖 Generated with Claude Code