Skip to content

Deploying zkde.fi

This page covers how the system is actually served — the reverse proxy, the process manager, the docs build pipeline, and the environment gates that control what's allowed to execute.

Runtime topology

flowchart LR
  U["Users"] --> RP["nginx<br/><i>:443, TLS</i>"]
  RP -->|"/"| FE["Next.js<br/><i>:3001</i>"]
  RP -->|"/api/"| BE["FastAPI<br/><i>:8003</i>"]
  RP -->|"/docs/"| DOCS["Static VitePress"]
  BE --> OBS["obsqra<br/><i>:8002</i>"]
  OBS --> MAD["Madara L3<br/><i>:9944</i>"]

Everything runs on a single server. nginx handles TLS and routes requests to the right service. There's no container orchestration — it's PM2 managing Node and Python processes.

ComponentPortWhat it is
Next.js frontend3001App shell, SSR pages, static assets
FastAPI backend8003API, WebSocket, proof orchestration, receipt lifecycle
obsqra backend8002Identity infrastructure, proof aggregation, GATE services
Madara L39944Local appchain for fact registration and L3 settlement
VitePress docsstaticBuilt once, copied into frontend/public/docs/, served by nginx

nginx routing

/           → localhost:3001   (Next.js)
/api/       → localhost:8003   (FastAPI)
/docs/      → frontend/public/docs/   (static, max-age=300)
/_next/     → .next/static/   (immutable cache)

The full nginx config lives at nginx/zkdefi.conf. Key behaviors:

  • /docs/ is served as static files with 5-minute cache headers
  • /_next/static/ is served with immutable cache headers (these are content-hashed)
  • /api/ is proxied with WebSocket upgrade support for the /ws/ path
  • Everything else falls through to Next.js

Docs build pipeline

After editing any docs page, rebuild and sync:

bash
./scripts/sync-docs.sh

This builds VitePress from docs-site/ and copies the output into frontend/public/docs/. From there, nginx serves it as static content. You don't need to restart the frontend or backend — just run the script.

The build preserves existing chunks during rebuild to avoid 404s on cached asset URLs. If you see chunk 404s after a deploy, it means someone ran a clean build that removed old hashes. Hard refresh (Ctrl+Shift+R) fixes it on the client side.

Process management

bash
pm2 start ecosystem.config.js   # Start everything
pm2 status                       # Check what's running
pm2 restart zkdefi-frontend      # Restart just the frontend
pm2 logs zkdefi-backend          # Tail backend logs

The PM2 config at ecosystem.config.js defines the process list. The frontend and backend are separate PM2 processes with their own log files.

Environment gates

The system uses environment variables to control what's allowed to execute. The most important one:

EXECUTION_GATE_ALLOW_MAINNET_LIVE=false

When this is false (the default), the system will not submit live capital transactions. Every execution path checks this gate. It's the master switch between testnet mode and mainnet mode.

Other key variables:

VariableWhat it controls
STARKNET_RPC_URLStarknet node endpoint (currently Sepolia)
MADARA_RPC_URLMadara L3 node endpoint
DATABASE_URLBackend database connection
EZKL_PATHPath to the EZKL binary for proof generation

Full list: docs/ENV.md in the repo.

References

  • docs/ENV.md — complete environment variable reference
  • docs/OPS_NGINX_ZKDEFI.md — detailed nginx configuration guide
  • docs/ARCHITECTURE.md — internal architecture documentation
  • nginx/zkdefi.conf — the actual nginx config file

Built by Obsqra Labs