Read-Node Same-Domain Deploy
Deployment target for serving the static frontend and the read node behind one origin so `/api/v1` becomes a real product rail instead of a documentation-only target.
Document context
Deployment target only; the current live site remains static until a separate backend host and reverse proxy are actually cut over.
Audience: Operators, infra leads, reviewers
Open raw fileRead Node Same-Domain Deploy
Goal
Serve the static PrivateDAO frontend and the read node behind the same origin so the browser uses:
- wallet-signed writes in the client
- pooled backend reads on
/api/v1 - direct RPC only as fallback
Deployment Target
The repo now carries a concrete primary-host target in:
- deploy/primary-host/docker-compose.yml
- deploy/primary-host/Caddyfile
- deploy/primary-host/read-node.Dockerfile
- deploy/primary-host/.env.example
- primary-host-bootstrap.md
Target runtime shape:
- primary static frontend
https://privatedao.org/- same-origin read node
https://privatedao.org/api/v1/*- public health and metrics
https://privatedao.org/healthzhttps://privatedao.org/api/v1/metrics- any legacy static mirror
- non-canonical only if still needed operationally
Read Node Process
The stack runs:
read-node- containerized
npm run start:read-node - bound internally to
read-node:8787 edge- Caddy reverse proxy
- serves the static export
- proxies
/healthzand/api/v1/*
Reverse Proxy Shape
Exact path mapping:
/- static export from
dist/web-mirror-root /healthz- reverse proxy to
http://read-node:8787/healthz /api/v1/*- reverse proxy to
http://read-node:8787/api/v1/*
The edge layer also adds:
X-PrivateDAO-Primary-Host: candidateX-PrivateDAO-Backup-Policy: github-pages-backup-only
Config Contract
Copy:
cp deploy/primary-host/.env.example deploy/primary-host/.envThen set:
PRIMARY_DOMAIN=privatedao.orgACME_EMAIL=...- one or more Devnet RPC credentials:
ALCHEMY_DEVNET_RPC_URL- or
ALCHEMY_API_KEY - or
HELIUS_API_KEY - or
SOLANA_RPC_URL PRIVATE_DAO_PROGRAM_IDif you want explicit override
For rehearsal the stack exposes:
- local verification edge:
http://127.0.0.1:8080 - candidate production edge HTTP: host bind from
PRIMARY_EDGE_HTTP_BIND_PORT - candidate production edge HTTPS: host bind from
PRIMARY_EDGE_HTTPS_BIND_PORT
Commands
cd PrivateDAO
npm run deploy:primary-host:prepare
npm run deploy:primary-host:up
npm run install:primary-host-stackTo stop it:
cd PrivateDAO
npm run deploy:primary-host:downTo verify the whole stack locally:
cd PrivateDAO
npm run verify:primary-host-stack
npm run verify:remote-primary-host -- https://privatedao.orgVerification
After deployment, verify:
curl https://privatedao.org/healthz
curl https://privatedao.org/api/v1/runtime
curl https://privatedao.org/api/v1/ops/overview
curl https://privatedao.org/api/v1/devnet/profiles
curl https://privatedao.org/api/v1/metricsFor local rehearsal, the same checks should pass at:
curl http://127.0.0.1:8080/healthz
curl http://127.0.0.1:8080/api/v1/runtime
curl http://127.0.0.1:8080/api/v1/metricsThe repo verifier currently asserts:
- root route serves the static PrivateDAO bundle
/healthzreportshealthy/api/v1/configreportsbackend-indexer/api/v1/metricsreturns counters/api/v1/ops/snapshotstill advertises/api/v1
DNS-Cutover Boundary
After the stack passes local verification, the remaining external work is:
- provision the host/VPS
- copy
deploy/primary-host/.env - run
npm run deploy:primary-host:up - bind
PRIMARY_EDGE_HTTP_BIND_PORT=80andPRIMARY_EDGE_HTTPS_BIND_PORT=443 - point
privatedao.orgDNS to that host - run
npm run verify:host-topology:strict
At that point GitHub Pages should no longer be treated as a public entrypoint.
privatedao.org/remains the canonical public surface- any historical GitHub Pages mirror should stay unpublished and non-canonical
In the Runtime Panel and operator routes, confirm:
READ PATH = Backend IndexerREFHE BACKENDshows live counts350-WALLET PROFILEshows the seven-wave planREAD NODE METRICSshows requests, failures, and rate-limited counters
Security Notes
- keep the read node read-only
- do not move any signing key or treasury authority server-side
- keep rate limiting enabled
- keep CORS pinned to
https://privatedao.orgafter cutover - terminate TLS at the reverse proxy
- keep backend logs and route-hit metrics enabled for operator review
Related next docs
Operational brief for DAO-controlled micropayment batches, showing how approved policy becomes batched stablecoin settlement with judge-visible runtime proof and telemetry continuity.
Shortest reviewer path across live proof, V3 hardening, trust links, and launch boundary surfaces.
Generated reviewer-visible route into telemetry, hosted reads, runtime evidence, indexed governance, and the infrastructure value layer behind PrivateDAO.