PRODUCTION DEPLOYMENT - nself-org/cli GitHub Wiki
Complete guide for deploying nself to production environments with automatic SSL, security hardening, and zero-downtime deployments.
# 1. Initialize your server (one-time setup)
nself server init [email protected] --domain example.com
# 2. Create production environment
nself env create prod prod
# 3. Generate secure secrets
nself config secrets generate --env prod
# 4. Validate before deployment
nself config validate prod
# 5. Deploy to production
nself deploy prodThe nself server init command prepares a fresh VPS for nself deployment:
nself server init <host> [options]- System Update: Updates packages and installs Docker + Docker Compose
- Security Hardening: Configures firewall (UFW), fail2ban, SSH hardening
-
nself Environment: Creates
/var/www/nselfdirectory structure - DNS Fallback: Configures reliable DNS resolution (Cloudflare, Google fallback)
- SSL Certificates: Automatic Let's Encrypt setup (if domain points to server)
| Option | Description |
|---|---|
--host, -h |
Server hostname or IP |
--user, -u |
SSH user (default: root) |
--port, -p |
SSH port (default: 22) |
--key, -k |
SSH private key file |
--domain, -d |
Domain for SSL setup |
--env, -e |
Environment name (default: prod) |
--skip-ssl |
Skip SSL certificate setup |
--skip-dns |
Skip DNS fallback configuration |
--yes, -y |
Skip confirmation prompts |
# Basic server setup
nself server init [email protected]
# With domain and custom SSH key
nself server init [email protected] --domain example.com --key ~/.ssh/deploy_key
# Non-interactive (for automation)
nself server init [email protected] --domain example.com --yes- Hetzner Cloud
- DigitalOcean
- Vultr
- Linode
- AWS EC2
- Google Cloud
- Azure
- Any VPS with SSH access
Production deployments require secure, randomly-generated secrets.
nself config secrets generate --env prodThis creates .environments/prod/.env.secrets with:
-
POSTGRES_PASSWORD(44 chars) -
HASURA_GRAPHQL_ADMIN_SECRET(64 chars) -
AUTH_JWT_SECRET(64 chars) -
REDIS_PASSWORD(44 chars) -
MINIO_ROOT_PASSWORD(44 chars) -
MEILISEARCH_MASTER_KEY(44 chars) -
GRAFANA_ADMIN_PASSWORD(32 chars) -
ENCRYPTION_KEY(32 chars)
nself config secrets validate --env prod# Rotate a single secret
nself config secrets rotate POSTGRES_PASSWORD --env prod
# Rotate all secrets (requires service restart)
nself config secrets rotate --all --env prod# Masked view
nself config secrets show --env prod
# Unmask values (use with caution)
nself config secrets show --env prod --unmaskAlways validate before deploying to production:
nself config validate prod-
Configuration Files
-
.envfile exists and is valid -
docker-compose.ymlis valid - nginx configuration is present
- SSL certificates exist
-
-
Security Settings
- All required secrets are set
- Passwords meet minimum length requirements
- No insecure default values
- Services bound to localhost only
-
Deployment Readiness
- Docker is running
- SSH connectivity to server
- Git status (uncommitted changes warning)
- Recent backup exists
For production, use strict mode to treat warnings as errors:
nself config validate prod --strictAttempt to automatically fix issues:
nself config validate prod --fixWhen deploying to production (ENV=prod), nself automatically runs security checks:
POSTGRES_PASSWORDHASURA_GRAPHQL_ADMIN_SECRETAUTH_JWT_SECRET
- Passwords containing:
password,changeme,secret,admin,12345 - Services bound to
0.0.0.0instead of127.0.0.1
- Passwords shorter than recommended length
- Let's Encrypt not configured
- Admin services enabled in production
To bypass security checks (NOT RECOMMENDED):
nself deploy production --forcenself handles SSL automatically based on environment:
- Uses mkcert for trusted local certificates
- Certificates for
*.localhostand*.local.nself.org - Run
nself trustto install root CA
- Attempts Let's Encrypt staging certificates
- Falls back to mkcert if DNS not configured
- Automatic Let's Encrypt certificates
- Requires DNS pointing to server OR DNS API configured
- Auto-renewal via cron job
For wildcard certificates, configure DNS provider:
# In .env.prod
DNS_PROVIDER=cloudflare
DNS_API_TOKEN=your-cloudflare-api-tokenSupported DNS providers:
-
cloudflare- Cloudflare -
route53- AWS Route53 -
digitalocean- DigitalOcean
# Check SSL status
nself auth ssl status
# Force regenerate certificates
nself auth ssl bootstrap
# Renew Let's Encrypt certificates
nself auth ssl renewnself deploy productionnself deploy production --dry-runnself deploy production --rollingnself deploy production --skip-health# Include frontends (default for staging)
nself deploy staging --include-frontends
# Exclude frontends (default for production)
nself deploy production --exclude-frontendsAfter deployment, nself validates:
- Docker services running
- nginx responding
- Database connectivity
- HTTP endpoints
nself deploy health --env prodnself doctorIf deployment fails:
nself backup rollback --env prodAlways backup before major deployments:
# Create full backup
nself backup create
# Create database-only backup
nself backup create database
# Configure cloud backup
nself backup cloud setupnself server check [email protected]nself deploy logs --env prodnself doctornself doctor --fix.environments/
โโโ staging/
โ โโโ .env # Configuration
โ โโโ .env.secrets # Sensitive credentials (chmod 600)
โ โโโ server.json # SSH connection details
โโโ prod/
โโโ .env
โโโ .env.secrets
โโโ server.json
{
"host": "server.example.com",
"port": 22,
"user": "root",
"key": "~/.ssh/deploy_key",
"deploy_path": "/var/www/nself",
"project_subdir": ""
}deploy_path โ Where your project lives on the server (default: /var/www/nself). Set this if your project is deployed to a custom path (e.g. /opt/myapp).
project_subdir โ Optional subdirectory within deploy_path where the nself .env files and nself build should run (used for monorepos). Leave empty for standard deployments.
Example for a monorepo with backend in a subdirectory:
{
"host": "server.example.com",
"port": 22,
"user": "root",
"key": "~/.ssh/deploy_key",
"deploy_path": "/opt/myapp",
"project_subdir": "backend"
}| Variable | Description | Required |
|---|---|---|
ENV |
Environment name (dev/staging/prod) | Yes |
PROJECT_NAME |
Docker project prefix | Yes |
BASE_DOMAIN |
Base domain for services | Yes |
DEPLOY_HOST |
SSH hostname | For deploy |
DNS_PROVIDER |
Let's Encrypt DNS provider | For wildcard SSL |
DNS_API_TOKEN |
DNS provider API token | For wildcard SSL |
-
Always validate before deploying:
nself config validate prod - Use separate secrets per environment: Never share production secrets
-
Backup before major changes:
nself backup create -
Use dry-run first:
nself deploy production --dry-run -
Monitor after deployment:
nself doctor - Rotate secrets regularly: Every 90 days minimum
-
Keep secrets out of git: Use
.env.secrets(gitignored)