Managing Environments
Work with local, staging, and production environments in your NNO platform.
Managing Environments
NNO uses three environments: local, staging, and production. Each has its own service URLs, Cloudflare resource bindings, and DNS hostnames. This guide walks you through setting each one up and deploying to it.
The three-environment model
| Environment | Purpose | Frontend | Backend |
|---|---|---|---|
| Local | Day-to-day development | Vite dev server (localhost:5174) | Wrangler dev (localhost:8787) |
| Staging | Pre-production validation | Cloudflare Pages preview | Workers with [env.stg] config |
| Production | Live platform | Cloudflare Pages production | Workers default config |
Staging and production each use a separate Cloudflare Pages project for full isolation. CF Pages custom domains always route to the production deployment of a project, so a single project cannot serve both environments on custom domains.
Environment file structure
apps/console/
├── .env # Local — gitignored (may contain local secrets)
├── .env.example # Template committed to repo
├── .env.stg # Staging — committed (VITE_* public vars only)
└── .env.prod # Production — committed (VITE_* public vars only)
services/<name>/
└── .dev.vars # Local Worker secrets — gitignored.env.stg and .env.prod are safe to commit because they contain only VITE_* variables — Vite bakes these into the JavaScript bundle at build time. Never put API keys or secrets in these files.
Local development
One-time setup:
cp apps/console/.env.example apps/console/.envEdit .env with local values:
VITE_AUTH_API_URL=/api/auth # Vite proxy → localhost:8787
VITE_API_URL=http://localhost:8787/api
VITE_PLATFORM_ID=<platformId>Start the frontend and any Workers you need locally:
# Frontend (http://localhost:5174)
cd apps/console && pnpm dev
# IAM Worker (http://localhost:8787)
cd services/iam && NODE_ENV=development pnpm devThe Vite proxy routes /api/auth requests to localhost:8787, so auth cookies are set as same-origin and work without CORS configuration.
For Worker secrets in local development, create a .dev.vars file in the service directory (gitignored):
# services/iam/.dev.vars
AUTH_API_KEY=dev-secret-hereStaging environment
Staging services live under *.stg.nno.app:
# apps/console/.env.stg
VITE_APP_ENV=stg
VITE_AUTH_API_URL=https://iam.svc.stg.nno.app
VITE_GATEWAY_URL=https://gateway.svc.stg.nno.app
VITE_PLATFORM_ID=<platformId>Deploy the console to staging by pushing to the develop branch. The GitHub Actions workflow builds with .env.stg and deploys to the staging Pages project. To deploy a Worker to staging:
cd services/gateway
wrangler deploy --env stgEach service's wrangler.toml defines [env.stg] with a -stg Worker name suffix, staging KV namespaces, and staging D1 database IDs.
Production environment
Production services live directly under *.nno.app:
# apps/console/.env.prod
VITE_APP_ENV=prod
VITE_GATEWAY_URL=https://gateway.svc.nno.app
VITE_AUTH_API_URL=https://iam.svc.nno.app
VITE_PLATFORM_ID=<platformId>Production deployment checklist:
- Secrets configured via
wrangler secret putor Cloudflare dashboard - D1 migrations applied:
pnpm --filter <service> with-env wrangler d1 migrations apply <db-name> - KV namespace IDs in
wrangler.tomlmatch production namespaces - DNS records verified in Cloudflare dashboard
-
.env.prodhas correct production service URLs
Deploy by pushing to main. For manual Worker deploys:
cd services/gateway
wrangler deploy # no --env flag = productionManaging secrets
Use Wrangler's secret management for staging and production — never commit secrets to any file:
# Set a secret for staging
wrangler secret put STRIPE_SECRET_KEY --env stg
# Set a secret for production
wrangler secret put STRIPE_SECRET_KEY
# List secret names (values are never shown)
wrangler secret listQuick reference
# Local
cp apps/console/.env.example apps/console/.env
cd apps/console && pnpm dev
# Staging build and deploy
pnpm --filter console build --mode stg
wrangler deploy --env stg # from service directory
# Production build and deploy
pnpm --filter console build --mode prod
wrangler deploy # from service directory
# Apply D1 migrations
pnpm --filter @neutrino-io/iam with-env wrangler d1 migrations apply nno-iam-dbNext steps
- DNS Setup — configure hostnames for each environment
- Deploy a Stack — provision Cloudflare resources
- API reference — Gateway service endpoints