Deployment
Deploy Niral to your own server or zHost. Learn production builds, nginx and systemd setup, atomic releases, rollback, environment checks and static export.
On this page 8 sections
Two ways to ship: zHost (ZyoraLabs' cloud — easiest, three commands) or your own server (the generated deploy kit — full control).
Deploy to zHost (ZyoraLabs cloud)
The fastest path from your machine to a live URL — no server to provision. zHost detects Niral automatically, builds with niral build, and runs your app in an isolated sandbox at https://<slug>.zyora.in.
curl -fsSL https://dl.zyora.in/zhost/install.sh | sh
zhost login
zhost link <slug>
zhost deploy # → https://<slug>.zyora.in
Full walkthrough — account, project, settings, how the build works, redeploys — on the dedicated Instant deploys · zHost page.
Deploy to your own server
Prefer your own box? niral deploy generates a complete, self-owned kit:
Atomic releases
niral build # dist/releases/<hash>/ — then dist/current flips atomically
niral start # serves dist/current
niral deploy # generates deploy/ — setup.sh (one-time Linux provisioning:
# node 22, systemd, nginx, generated NIRAL_SECRET), deploy.sh
# (rsync → build ON the server → restart → health check),
# systemd unit, nginx conf, Dockerfile. Templates you own.
- A failed build never touches production — the flip only happens on success
- The last 5 releases stay on disk: rollback = repoint one symlink
- Assets are served under versioned paths with
immutablecaching; stale
hashes from mid-deploy sessions redirect to the current release
data/lives outside releases — SQLite databases survive every deploy
Graceful shutdown
niral start drains on SIGTERM/SIGINT (what systemctl restart sends): it stops accepting, lets in-flight requests finish, sends live WebSockets a proper close frame so clients reconnect to the new process, stops jobs and workers — then exits. A deploy never drops work mid-request.
Required environment
Declare what the app cannot run without in hooks.js:
export const env = ["STRIPE_KEY", "SMTP_PASS"]
Production refuses to boot when any are missing — the failure happens at deploy time with a message naming them, not at 3am mid-request. Dev warns.
Security defaults
Every production response ships CSP with per-request nonces, nosniff, frame denial and referrer policy. Sessions are HttpOnly + SameSite (+ Secure with NIRAL_SECURE=1). RPC requires a CSRF header and is rate limited. Page caching: <script cache="120"> sets stale-while-revalidate headers.
Static export
niral export # prerenders every parameterless route to out/
Pretty URLs, hashed assets, custom 404 — host it anywhere. Client pages still hydrate; server features (RPC, actions) need niral start.
Environment
| Variable | Purpose |
|---|---|
NIRAL_SECRET | session signing key (set it in production!) |
NIRAL_SECURE=1 | Secure cookies behind HTTPS |
NIRAL_SESSION_STORE=db | server-side session data |
NIRAL_LOG, NIRAL_ACCESS_LOG, NIRAL_SLOW_MS | logging |
NIRAL_AI_URL/KEY/MODEL | AI endpoint |
NIRAL_SMTP_URL, NIRAL_MAIL_FROM | |
NIRAL_SNAPSHOT_REMOTE_* | encrypted S3-compatible off-box snapshots |
NIRAL_WORKERS | polyglot worker pool size |