PRODUCTION DEPLOYMENT - nself-org/cli GitHub Wiki

Production Deployment Guide

Complete guide for deploying nself to production environments with automatic SSL, security hardening, and zero-downtime deployments.

Quick Start

# 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 prod

Server Initialization

The nself server init command prepares a fresh VPS for nself deployment:

nself server init <host> [options]

What It Does

  1. System Update: Updates packages and installs Docker + Docker Compose
  2. Security Hardening: Configures firewall (UFW), fail2ban, SSH hardening
  3. nself Environment: Creates /var/www/nself directory structure
  4. DNS Fallback: Configures reliable DNS resolution (Cloudflare, Google fallback)
  5. SSL Certificates: Automatic Let's Encrypt setup (if domain points to server)

Options

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

Examples

# 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

Supported Providers

  • Hetzner Cloud
  • DigitalOcean
  • Vultr
  • Linode
  • AWS EC2
  • Google Cloud
  • Azure
  • Any VPS with SSH access

Secrets Management

Production deployments require secure, randomly-generated secrets.

Generate Secrets

nself config secrets generate --env prod

This 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)

Validate Secrets

nself config secrets validate --env prod

Rotate Secrets

# 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

View Secrets

# Masked view
nself config secrets show --env prod

# Unmask values (use with caution)
nself config secrets show --env prod --unmask

Pre-deployment Validation

Always validate before deploying to production:

nself config validate prod

What's Validated

  1. Configuration Files

    • .env file exists and is valid
    • docker-compose.yml is valid
    • nginx configuration is present
    • SSL certificates exist
  2. Security Settings

    • All required secrets are set
    • Passwords meet minimum length requirements
    • No insecure default values
    • Services bound to localhost only
  3. Deployment Readiness

    • Docker is running
    • SSH connectivity to server
    • Git status (uncommitted changes warning)
    • Recent backup exists

Strict Mode

For production, use strict mode to treat warnings as errors:

nself config validate prod --strict

Auto-fix

Attempt to automatically fix issues:

nself config validate prod --fix

Security Pre-flight Checks

When deploying to production (ENV=prod), nself automatically runs security checks:

Blocked if Missing

  • POSTGRES_PASSWORD
  • HASURA_GRAPHQL_ADMIN_SECRET
  • AUTH_JWT_SECRET

Blocked if Insecure

  • Passwords containing: password, changeme, secret, admin, 12345
  • Services bound to 0.0.0.0 instead of 127.0.0.1

Warned

  • Passwords shorter than recommended length
  • Let's Encrypt not configured
  • Admin services enabled in production

Force Deploy

To bypass security checks (NOT RECOMMENDED):

nself deploy production --force

SSL Certificates

nself handles SSL automatically based on environment:

Development (ENV=dev)

  • Uses mkcert for trusted local certificates
  • Certificates for *.localhost and *.local.nself.org
  • Run nself trust to install root CA

Staging (ENV=staging)

  • Attempts Let's Encrypt staging certificates
  • Falls back to mkcert if DNS not configured

Production (ENV=prod)

  • Automatic Let's Encrypt certificates
  • Requires DNS pointing to server OR DNS API configured
  • Auto-renewal via cron job

DNS-based SSL (Wildcard Certificates)

For wildcard certificates, configure DNS provider:

# In .env.prod
DNS_PROVIDER=cloudflare
DNS_API_TOKEN=your-cloudflare-api-token

Supported DNS providers:

  • cloudflare - Cloudflare
  • route53 - AWS Route53
  • digitalocean - DigitalOcean

Manual SSL Commands

# Check SSL status
nself auth ssl status

# Force regenerate certificates
nself auth ssl bootstrap

# Renew Let's Encrypt certificates
nself auth ssl renew

Deployment

Standard Deployment

nself deploy production

Dry Run (Preview)

nself deploy production --dry-run

Rolling Deployment (Zero-downtime)

nself deploy production --rolling

Skip Health Checks

nself deploy production --skip-health

Include/Exclude Frontends

# Include frontends (default for staging)
nself deploy staging --include-frontends

# Exclude frontends (default for production)
nself deploy production --exclude-frontends

Health Checks

After deployment, nself validates:

  1. Docker services running
  2. nginx responding
  3. Database connectivity
  4. HTTP endpoints

Manual Health Check

nself deploy health --env prod

Detailed Health Report

nself doctor

Rollback

If deployment fails:

nself backup rollback --env prod

Backup Before Deploy

Always backup before major deployments:

# Create full backup
nself backup create

# Create database-only backup
nself backup create database

# Configure cloud backup
nself backup cloud setup

Troubleshooting

Check Server Readiness

nself server check [email protected]

View Deployment Logs

nself deploy logs --env prod

Diagnose Issues

nself doctor

Fix Common Issues

nself doctor --fix

Environment Configuration

Directory Structure

.environments/
โ”œโ”€โ”€ staging/
โ”‚   โ”œโ”€โ”€ .env           # Configuration
โ”‚   โ”œโ”€โ”€ .env.secrets   # Sensitive credentials (chmod 600)
โ”‚   โ””โ”€โ”€ server.json    # SSH connection details
โ””โ”€โ”€ prod/
    โ”œโ”€โ”€ .env
    โ”œโ”€โ”€ .env.secrets
    โ””โ”€โ”€ server.json

server.json Format

{
  "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"
}

Environment Variables

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

Best Practices

  1. Always validate before deploying: nself config validate prod
  2. Use separate secrets per environment: Never share production secrets
  3. Backup before major changes: nself backup create
  4. Use dry-run first: nself deploy production --dry-run
  5. Monitor after deployment: nself doctor
  6. Rotate secrets regularly: Every 90 days minimum
  7. Keep secrets out of git: Use .env.secrets (gitignored)
โš ๏ธ **GitHub.com Fallback** โš ๏ธ