NNO Docs
Platform DocsAPI ReferenceInternal
Guides

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

EnvironmentPurposeFrontendBackend
LocalDay-to-day developmentVite dev server (localhost:5174)Wrangler dev (localhost:8787)
StagingPre-production validationCloudflare Pages previewWorkers with [env.stg] config
ProductionLive platformCloudflare Pages productionWorkers 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/.env

Edit .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 dev

The 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-here

Staging 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 stg

Each 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 put or Cloudflare dashboard
  • D1 migrations applied: pnpm --filter <service> with-env wrangler d1 migrations apply <db-name>
  • KV namespace IDs in wrangler.toml match production namespaces
  • DNS records verified in Cloudflare dashboard
  • .env.prod has correct production service URLs

Deploy by pushing to main. For manual Worker deploys:

cd services/gateway
wrangler deploy    # no --env flag = production

Managing 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 list

Quick 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-db

Next steps

On this page