DEPLOYMENT ARCHITECTURE - nself-org/cli GitHub Wiki
This guide explains how nself deploys services across different environments and the distinction between staging and production deployments.
nself organizes services into five distinct categories:
These are the foundational services required for any nself deployment:
| Service | Purpose | Subdomain |
|---|---|---|
| PostgreSQL | Primary database | Internal only |
| Hasura | GraphQL API engine | api.domain.com |
| Auth | Authentication service (nhost-compatible) | auth.domain.com |
| Nginx | Reverse proxy & SSL termination | Main entry point |
Enable these based on your application needs:
| Service | Enable Flag | Subdomain | Purpose |
|---|---|---|---|
| nself-admin | NSELF_ADMIN_ENABLED=true |
admin.domain.com |
Web management UI |
| MinIO | MINIO_ENABLED=true |
minio.domain.com |
S3-compatible storage |
| Redis | REDIS_ENABLED=true |
Internal | Cache & sessions |
| Functions | FUNCTIONS_ENABLED=true |
functions.domain.com |
Serverless runtime |
| MLflow | MLFLOW_ENABLED=true |
mlflow.domain.com |
ML experiment tracking |
| Mailpit | MAILPIT_ENABLED=true |
mail.domain.com |
Dev email testing |
| Meilisearch | MEILISEARCH_ENABLED=true |
search.domain.com |
Full-text search |
When MONITORING_ENABLED=true, all 10 services are deployed:
| Service | Purpose |
|---|---|
| Prometheus | Metrics collection |
| Grafana | Dashboards & visualization |
| Loki | Log aggregation |
| Promtail | Log shipping (required for Loki) |
| Tempo | Distributed tracing |
| Alertmanager | Alert routing |
| cAdvisor | Container metrics |
| Node Exporter | System metrics |
| Postgres Exporter | Database metrics |
| Redis Exporter | Redis metrics |
Completely independent backend applications with custom business logic:
# In .env
CS_1=order-api:express-js:8001 # Order processing API
CS_2=webhooks:nestjs:8002 # Webhook handler service
CS_3=payments:fastapi-py:8003 # Payment processing
CS_4=ml-inference:fastapi-py:8004 # ML model servingCustom services are separate applications that:
- Have their own codebase and logic
- May or may not connect to the database
- Run as independent Docker containers
- Can integrate with Hasura via Actions/Event Triggers
Examples:
- Order processing API
- Payment processing service
- Email notification worker
- ML inference endpoint
- Third-party integration handlers (webhooks, callbacks)
Different from Custom Services! Remote Schemas are multiple Hasura GraphQL endpoints for different apps/tenants, all accessing the same database with different exposed schemas:
Same nself instance, same PostgreSQL, different GraphQL APIs:
api.app1.com โ Hasura endpoint exposing App1 tables/permissions
api.app2.com โ Hasura endpoint exposing App2 tables/permissions
Use case: One nself deployment serving multiple applications:
-
www.app1.comusesapi.app1.com(sees users, products, orders) -
www.app2.comusesapi.app2.com(sees different tables/fields)
Configuration in .env:
# Remote Schemas (multiple Hasura endpoints)
REMOTE_SCHEMA_1_NAME=app1
REMOTE_SCHEMA_1_DOMAIN=api.app1.com
REMOTE_SCHEMA_2_NAME=app2
REMOTE_SCHEMA_2_DOMAIN=api.app2.comFrontend applications configured for Nginx routing:
# In .env
FRONTEND_APP_1_NAME=web
FRONTEND_APP_1_PORT=3000
FRONTEND_APP_1_ROUTE=app
FRONTEND_APP_2_NAME=admin
FRONTEND_APP_2_PORT=3001
FRONTEND_APP_2_ROUTE=dashboardKey Point: These are NOT Docker containers - they run outside Docker and Nginx routes to them.
๐ KEY DIFFERENCE: Frontend apps are included in staging (complete testing environment) but excluded in production (deployed separately to Vercel/CDN).
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LOCAL DEVELOPMENT โ
โ nself init โ nself build โ nself start โ
โ All services run in Docker on localhost โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STAGING โ
โ nself deploy staging โ
โ โ
โ โ
Deploys: Core + Optional + Monitoring + Custom + Frontends โ
โ โ
โ Frontend apps served by Nginx on subdomains: โ
โ app.staging.example.com โ Frontend App 1 โ
โ dashboard.staging.example.com โ Frontend App 2 โ
โ โ
โ Complete replica for testing everything together โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PRODUCTION โ
โ nself deploy production โ
โ โ
โ โ
Deploys: Core + Optional + Monitoring + Custom โ
โ โ Frontend apps EXCLUDED by default (deploy separately) โ
โ โ
โ Frontend apps deployed to specialized platforms: โ
โ โโโ Vercel (Next.js, React) - Auto-scaling, edge cache โ
โ โโโ Cloudflare Pages (static) - Global CDN โ
โ โโโ Mobile apps (App Store, Play Store) โ
โ โโโ Any CDN/hosting platform โ
โ โ
โ API endpoints exposed: โ
โ api.example.com โ Hasura GraphQL โ
โ auth.example.com โ Authentication โ
โ โ
โ ๐ก Override: Use --include-frontends to deploy frontends โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๏ธ IMPORTANT: The key difference is frontend app deployment behavior!
| Aspect | Staging | Production |
|---|---|---|
| Frontend Apps | โ INCLUDED (Nginx serves) | โ EXCLUDED (Vercel/CDN) |
| Hasura Console | โ Enabled | โ Disabled |
| Debug Mode | โ Off | โ Off |
| Log Level | info |
warning |
| Mailpit | โ Available | โ Use real email |
| Monitoring | โ Required | |
| Purpose | Testing & QA | Live users |
๐ก TL;DR: Staging = test everything together. Production = backend on VPS, frontends on specialized platforms.
Staging: You want a complete replica to test everything together - frontend, backend, APIs, integrations. Nginx serves all frontend apps on staging subdomains. This ensures your staging environment matches the full user experience.
Production: Frontend apps have different scaling needs and are typically deployed on specialized platforms:
- Vercel/Netlify: Automatic scaling, edge caching, preview deployments, serverless functions
- Cloudflare Pages: Global CDN with 200+ edge locations, instant cache invalidation
- Mobile Apps: App Store / Google Play (can't run on your VPS anyway)
Why separate?
- โ Better performance (global CDN vs single VPS)
- โ Lower costs (frontend hosting is often free)
- โ Easier deployment (Git push vs Docker rebuild)
- โ Better DX (preview deployments, instant rollbacks)
Your VPS focuses on what it does best: running the backend services, APIs, and databases.
# Initialize staging
nself staging init staging.example.com --email [email protected]
# Configure server
# Edit .environments/staging/server.json
# Generate secrets
nself staging secrets generate
# Deploy everything
nself staging deploy
# What gets deployed:
# โ Core Services (PostgreSQL, Hasura, Auth, Nginx)
# โ Optional Services (based on *_ENABLED)
# โ Monitoring Bundle (if enabled)
# โ Custom Services (CS_1, CS_2, ...)
# โ Frontend Apps (FRONTEND_APP_1, FRONTEND_APP_2, ...)# Initialize production
nself prod init example.com --email [email protected]
# Configure server
# Edit .environments/prod/server.json
# Generate secrets
nself prod secrets generate
# Security audit
nself prod check
# Deploy backend only
nself deploy prod
# What gets deployed:
# โ Core Services (PostgreSQL, Hasura, Auth, Nginx)
# โ Optional Services (based on *_ENABLED)
# โ Monitoring Bundle (if enabled)
# โ Custom Services (CS_1, CS_2, ...)
# โ Frontend Apps (excluded - deploy to Vercel/CDN)# Force include frontends in production (unusual)
nself deploy prod --include-frontends
# Exclude frontends in staging (e.g., testing backend only)
nself staging deploy --exclude-frontendsnself can serve multiple applications from one deployment using Remote Schemas - different Hasura GraphQL endpoints with different exposed schemas, all hitting the same database:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ nself Deployment โ
โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ api.app1.com โ โ api.app2.com โ โ api.main โ โ
โ โ (Remote 1) โ โ (Remote 2) โ โ (Default) โ โ
โ โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโ โ
โ โ PostgreSQL โ โ
โ โ (Same Database)โ โ
โ โโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Use case: SaaS platform serving multiple white-label apps from one backend.
Custom Services (CS_N) are separate backend applications that can integrate with Hasura:
Your Custom Service handles business logic called from GraphQL:
# Custom service for complex operations
CS_1=order-service:nestjs:8001In Hasura Console โ Actions:
- Handler URL:
http://order-service:8001/validate-and-process - Expose as:
processOrdermutation - Hasura handles auth, your service handles logic
Your Custom Service reacts to database changes:
# Worker service for async processing
CS_2=notification-worker:express-js:8002In Hasura Console โ Events:
- Webhook URL:
http://notification-worker:8002/on-order-created - Trigger on:
INSERTintoorderstable - Your service sends emails, updates analytics, etc.
Custom Services can also be completely independent:
# Telemetry API (no Hasura integration)
CS_3=telemetry:express-js:8003
# ML inference (no Hasura integration)
CS_4=ml-api:fastapi-py:8004These run alongside nself but handle their own routing and logic.
my-project/
โโโ .environments/
โ โโโ staging/
โ โ โโโ .env # Staging config
โ โ โโโ .env.secrets # Staging secrets
โ โ โโโ server.json # Staging VPS SSH config
โ โโโ prod/
โ โโโ .env # Production config
โ โโโ .env.secrets # Production secrets
โ โโโ server.json # Production VPS SSH config
โโโ .env.dev # Local development config
โโโ docker-compose.yml # Generated by nself build
โโโ nginx/ # Generated nginx configs
โโโ services/ # Generated custom services
โ โโโ payment_api/ # CS_1
โ โโโ event_worker/ # CS_2
โ โโโ ml_inference/ # CS_3
โโโ frontend/ # Your frontend apps (not in Docker)
โโโ web/ # Next.js app โ Vercel in prod
โโโ mobile/ # React Native โ App stores
- Staging mirrors production config - Same services, same structure
- Test everything in staging - Including frontend integrations
- Production is backend-focused - Let specialized platforms handle frontends
- Use Hasura for API - Custom services extend, don't replace it
- Monitor everything - Enable monitoring bundle in staging and production
- Secure secrets - Different secrets per environment, never commit them
- nself env - Environment management
- nself staging - Staging commands
- nself prod - Production commands
- nself deploy - Deployment commands
- Custom Services - CS_N configuration