Add deployment: Dockerfile, compose, proxy config, and docs
One container plus a Postgres behind any TLS-terminating proxy. Nothing is specific to a particular host. The app and API are served from a SINGLE origin. This is not tidiness: browser auth sessions live in per-origin storage, so splitting them across two hostnames makes sign-in loop in a way that presents as a server fault. The short alias redirects rather than serving a second origin. Two safety properties verified by running the image, not by reading the code: - With NODE_ENV=production and no SUPABASE_URL, the process refuses to start and says why. Serving the whole CRM unauthenticated is a worse outcome than failing to deploy, so the failure is deliberate and loud. - In production the development auth bypass does not apply: an unauthenticated request to /api/dashboard returns 401 rather than adopting the first user in the table. The Dockerfile typechecks all six packages as a build gate, so a deploy that does not compile fails at build time rather than in front of a user. Runtime runs unprivileged as `node`, and Postgres is not published to the host. Docs cover the ontology and why it is shaped this way, agent connection for Claude Code / Codex / prime-agent / Buzz, and the provenance rules governing seed data about real people — including how to have your record removed. Verified: image builds, container reports healthy, serves the SPA, enforces auth, and the production guard exits non-zero. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Caddy — reverse proxy for PIG.
|
||||
#
|
||||
# Serve the app and the API from ONE hostname. Auth sessions live in
|
||||
# per-origin browser storage, so splitting them across two hostnames makes
|
||||
# sign-in loop endlessly in a way that looks like a server fault.
|
||||
|
||||
primeintellectgrowth.com, www.primeintellectgrowth.com {
|
||||
encode zstd gzip
|
||||
|
||||
# The MCP endpoint, when Streamable HTTP is enabled. Same origin as the
|
||||
# app so it shares the session and needs no CORS allowance.
|
||||
reverse_proxy 127.0.0.1:8920
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
X-Content-Type-Options "nosniff"
|
||||
X-Frame-Options "DENY"
|
||||
Referrer-Policy "strict-origin-when-cross-origin"
|
||||
# The app is entirely first-party except for the auth provider, which
|
||||
# it must reach over XHR.
|
||||
Content-Security-Policy "default-src 'self'; connect-src 'self' https://*.supabase.co; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; frame-ancestors 'none'; base-uri 'self'"
|
||||
-Server
|
||||
}
|
||||
}
|
||||
|
||||
# Short alias. A redirect rather than a second origin, deliberately — see above.
|
||||
pig.karti.ai {
|
||||
redir https://primeintellectgrowth.com{uri} permanent
|
||||
}
|
||||
Reference in New Issue
Block a user