Environment Management

Updated for nself v0.4.8


nself v0.4.7+ provides a comprehensive environment management system using the .environments/ directory structure. This enables you to maintain separate configurations for development, staging, and production with proper secrets management and SSH deployment.

Environment Overview

nself supports three primary environments, each stored in its own directory:

Development (dev)

Local development with debug tools, hot reloading, admin UI enabled, and relaxed security. Uses *.local.nself.org wildcard domains.

Staging

Production-like environment on a VPS for testing. Deploys full stack including frontends. Uses *.staging.yourdomain.com.

Production (prod)

Live production with security hardening, admin UI disabled, and backend-only deployment. Frontends typically deployed separately via Vercel/CDN.

Directory Structure

Each environment is stored in .environments/<name>/ with three files:

.environments/
├── dev/
│   ├── .env              # Development configuration
│   ├── .env.secrets      # Development secrets (git-ignored)
│   └── server.json       # Local server config (optional)
├── staging/
│   ├── .env              # Staging configuration
│   ├── .env.secrets      # Staging secrets (git-ignored, chmod 600)
│   └── server.json       # SSH connection details
└── prod/
    ├── .env              # Production configuration
    ├── .env.secrets      # Production secrets (git-ignored, chmod 600)
    └── server.json       # SSH connection details

Security Note

The .env.secrets files are automatically set to chmod 600 and should never be committed to git. Add .environments/*/.env.secrets to your .gitignore.

Environment Commands

List Environments

# List all environments (active marked with *)
nself env list

# Output:
# * dev      (active)
#   staging
#   prod

Switch Environments

# Switch to a different environment
nself env switch dev
nself env switch staging
nself env switch prod

# What happens:
# 1. Current .env files are backed up
# 2. Environment config is merged to .env.local
# 3. Current environment marker is updated

Create New Environment

# Create from template (local, staging, or prod)
nself env create dev
nself env create staging staging
nself env create prod prod

# Create QA environment from staging template
nself env create qa staging

Environment Status

# Show current environment status
nself env status

# Show environment info
nself env info staging

# Compare two environments
nself env diff staging prod
nself env diff dev staging --values

Validate Environment

# Validate configuration before deployment
nself env validate
nself env validate staging
nself env validate prod

Environment Files

.env File

Contains non-sensitive environment configuration:

# .environments/staging/.env
ENV=staging
DEBUG=false
BASE_DOMAIN=staging.myapp.com

# Services
NSELF_ADMIN_ENABLED=false
MINIO_ENABLED=true
REDIS_ENABLED=true
MONITORING_ENABLED=true

# Database
POSTGRES_DB=myapp_staging

.env.secrets File

Contains sensitive credentials (chmod 600, git-ignored):

# .environments/staging/.env.secrets
POSTGRES_PASSWORD=your-secure-password
HASURA_GRAPHQL_ADMIN_SECRET=your-admin-secret
JWT_SECRET=your-jwt-secret-at-least-32-characters
MINIO_ROOT_PASSWORD=your-minio-password

server.json File

Contains SSH connection details for remote deployment:

{
  "name": "staging",
  "type": "staging",
  "host": "staging.myapp.com",
  "port": 22,
  "user": "deploy",
  "key": "~/.ssh/staging_key",
  "deploy_path": "/opt/nself"
}

Secrets Management

Generate Secrets

# Generate secrets for an environment
nself staging secrets generate
nself prod secrets generate

# This creates secure random values for:
# - POSTGRES_PASSWORD
# - HASURA_GRAPHQL_ADMIN_SECRET
# - JWT_SECRET
# - MINIO_ROOT_PASSWORD
# - etc.

View Secrets (Masked)

# View secrets with masked values
nself env info staging

# Compare environments (values masked)
nself env diff staging prod --values

Deployment Workflow

Development Workflow

# 1. Switch to dev environment
nself env switch dev

# 2. Build configuration
nself build

# 3. Start services locally
nself start

# 4. Check status
nself status
nself urls

Staging Deployment

# 1. Check SSH access
nself deploy check-access

# 2. Preview deployment
nself staging deploy --dry-run

# 3. Deploy to staging (full stack including frontends)
nself staging deploy

# 4. Check health
nself deploy health staging

Production Deployment

# 1. Check SSH access
nself deploy check-access

# 2. Preview deployment
nself deploy prod --dry-run

# 3. Deploy to production (backend only - frontends on Vercel/CDN)
nself deploy prod

# 4. Check health
nself deploy health prod

Environment-Specific Services

Development-Only Services

# Services enabled only in development
NSELF_ADMIN_ENABLED=true    # Admin UI at admin.local.nself.org
MAILPIT_ENABLED=true        # Email testing at mail.local.nself.org
SWAGGER_ENABLED=true        # API documentation

Production Security

# Production security settings
NSELF_ADMIN_ENABLED=false   # Admin UI DISABLED for security
MONITORING_ENABLED=true     # Enable Prometheus/Grafana
SSL_MODE=letsencrypt        # Real SSL certificates

Environment Cascade

When an environment is active, configuration loads in this order (later overrides earlier):

  1. .env.dev - Base development config
  2. .environments/<name>/.env - Environment-specific config
  3. .env.local - Generated merged config
  4. .environments/<name>/.env.secrets - Secrets

Shortcut Commands

# Staging shortcuts
nself staging deploy          # Deploy to staging
nself staging secrets generate # Generate staging secrets

# Production shortcuts
nself prod init myapp.com     # Initialize production
nself prod check              # Security audit
nself prod harden             # Apply security hardening
nself prod ssl request        # Request SSL certificate

Best Practices

Security

  • Never commit secrets - Add .environments/*/.env.secrets to .gitignore
  • Use separate SSH keys - Different keys for staging and production
  • Rotate secrets regularly - Regenerate secrets periodically
  • Validate before deploy - Always run nself env validate

Configuration

  • Keep environments similar - Minimize differences between staging and production
  • Document custom settings - Add comments to environment files
  • Use environment templates - Start from standard templates for consistency
  • Version control .env files - Commit .env files (not secrets) to git

Deployment

  • Test in staging first - Always deploy to staging before production
  • Use dry-run - Preview deployments with --dry-run
  • Check health - Verify deployment with nself deploy health
  • Have a rollback plan - Know how to rollback if issues occur

Troubleshooting

SSH Connection Failed

# Test connectivity
nself deploy check-access

# Ensure SSH key is added to server
ssh-copy-id -i ~/.ssh/my_key user@server

# Test manual connection
ssh -i ~/.ssh/my_key user@server

Environment Validation Errors

# Check what's missing
nself env validate staging

# Common fixes:
# - Missing .env.secrets: Run 'nself staging secrets generate'
# - Invalid server.json: Check host, port, user, key path
# - Missing required vars: Add to .env file

Deployment Health Check Failed

# Check deployment logs
nself deploy logs

# Check server directly
ssh user@server "cd /opt/nself && docker compose logs"

# Verify services are running
ssh user@server "cd /opt/nself && docker compose ps"

Next Steps

Proper environment management is crucial for reliable software delivery. Use the .environments/ structure to maintain clean separation between development, staging, and production configurations.