The nself deploy, nself staging, and nself prod commands provide a complete deployment pipeline for staging and production environments. This workflow uses the .environments/ directory structure introduced in v0.4.7.
.environments/ directory with per-environment configs.env.secrets files with 600 permissionsEnvironments are configured in the .environments/ directory:
.environments/
├── dev/
│ └── .env # Development config
├── staging/
│ ├── .env # Staging config
│ ├── .env.secrets # Sensitive credentials (chmod 600)
│ └── server.json # SSH connection details
└── prod/
├── .env # Production config
├── .env.secrets # Sensitive credentials (chmod 600)
└── server.json # SSH connection details{
"name": "staging",
"type": "staging",
"host": "staging.example.com",
"port": 22,
"user": "deploy",
"key": "~/.ssh/staging_deploy_key",
"deploy_path": "/opt/nself"
}Deploy your nself project to remote servers via SSH.
# Deploy to environment
nself deploy <environment>
# Examples
nself deploy staging # Deploy to staging
nself deploy prod # Deploy to production
# Preview deployment (dry-run)
nself deploy staging --dry-run
# Skip confirmation prompt
nself deploy prod --forcenself deploy <env> [options]
Options:
--dry-run Preview deployment without executing
--check-access Verify SSH connectivity before deploy
--force, -f Skip confirmation prompts
--rolling Use rolling deployment (zero-downtime)
--skip-health Skip health checks after deployment
--include-frontends Include frontend apps (default for staging)
--exclude-frontends Exclude frontend apps (default for production)
--backend-only Alias for --exclude-frontends# Check SSH access to all environments
nself deploy check-access
# View deployment status
nself deploy status
# Run health checks on deployment
nself deploy health [env]
nself deploy health staging
nself deploy health prod
# View remote logs
nself deploy logs
# Rollback last deployment
nself deploy rollback
# Interactive deployment setup
nself deploy initWhen you run nself deploy <env>, the following steps are executed:
1. Read .environments/<env>/server.json for SSH details
2. Validate SSH key and test connectivity
3. Run local 'nself build' to ensure configs are up-to-date
4. Create remote directory structure (if needed)
5. Use rsync (or scp fallback) to sync files
6. Copy .env and .env.secrets to remote
7. Run 'docker compose pull && docker compose up -d'
8. Verify health checks (unless --skip-health)
9. Show deployment summary# Files transferred to remote server:
docker-compose.yml # Service definitions
nginx/ # Reverse proxy config
postgres/ # Database init scripts
services/ # Custom service code (CS_N)
monitoring/ # Prometheus, Grafana configs
ssl/certificates/ # SSL certificates
.env # Environment config
.env.secrets # Sensitive credentials (chmod 600)Staging-specific commands for testing and data management.
# Initialize staging environment
nself staging init <domain> [options]
# Example
nself staging init staging.example.com \
--email admin@example.com \
--server staging-vps.example.com
# Creates .environments/staging/ with:
# - .env (staging-optimized config)
# - server.json (SSH connection - edit with credentials)
# - .env.secrets template# Deploy to staging (includes frontend apps by default)
nself staging deploy
# Preview deployment
nself staging deploy --dry-run
# Skip confirmations
nself staging deploy --force
# Deploy without frontend apps
nself staging deploy --exclude-frontends# Reset staging (stop and restart, keep data)
nself staging reset
# Reset and wipe all data
nself staging reset --data
# Skip confirmation
nself staging reset --force# Load test data into staging
nself staging seed [file]
# Auto-detect seed file
nself staging seed
# Looks in: seeds/staging.sql, seed/staging.sql, data/seed-staging.sql
# Use specific seed file
nself staging seed ./seeds/test-data.sql
# Force re-seed
nself staging seed --force# Sync production data to staging (preview)
nself staging sync
# Sync database only
nself staging sync db
# Sync files/storage only
nself staging sync files
# Force without confirmation
nself staging sync --force
# Note: Consider anonymizing sensitive data# Generate staging secrets
nself staging secrets generate
# Show secrets (masked)
nself staging secrets show# View staging logs
nself staging logs [service]
nself staging logs -f # Follow all
nself staging logs nginx -n 50 # Last 50 lines
# SSH into staging
nself staging shell # SSH to server
nself staging shell postgres # Shell into containerProduction hardening, security, and deployment commands.
# Initialize production configuration
nself prod init <domain> [--email <email>]
# Example
nself prod init example.com --email admin@example.com
# This sets:
# - ENV=prod
# - DEBUG=false
# - LOG_LEVEL=warning
# - SSL_ENABLED=true
# - SSL_PROVIDER=letsencrypt
# - HASURA_GRAPHQL_DEV_MODE=false
# - HASURA_GRAPHQL_ENABLE_CONSOLE=false
# - NSELF_ADMIN_ENABLED=false# Generate all production secrets
nself prod secrets generate
# Rotate specific secret
nself prod secrets rotate POSTGRES_PASSWORD
# Validate secrets
nself prod secrets validate
# Show secrets (masked)
nself prod secrets show
# Show secrets (unmasked - use carefully!)
nself prod secrets show --unmask
# Generated secrets include:
# - POSTGRES_PASSWORD
# - HASURA_GRAPHQL_ADMIN_SECRET
# - JWT_SECRET
# - COOKIE_SECRET
# - MINIO_ROOT_PASSWORD
# - REDIS_PASSWORD
# - GRAFANA_ADMIN_PASSWORD# Check certificate status
nself prod ssl status
# Request Let's Encrypt certificate
nself prod ssl request example.com --email admin@example.com
# Use staging (for testing)
nself prod ssl request example.com --staging
# Renew certificates
nself prod ssl renew
# Force renewal
nself prod ssl renew --force
# Generate self-signed (testing only)
nself prod ssl self-signed example.com
# Verify certificate chain
nself prod ssl verify# Check firewall status
nself prod firewall status
# Preview recommended rules
nself prod firewall configure --dry-run
# Apply recommended rules
nself prod firewall configure
# Allow specific port
nself prod firewall allow 8080
# Block specific port
nself prod firewall block 8080
# Show recommendations
nself prod firewall recommendations
# Recommended ports:
# - 22/tcp SSH
# - 80/tcp HTTP (redirect to HTTPS)
# - 443/tcp HTTPS# Apply all hardening measures
nself prod harden
# Preview hardening steps
nself prod harden --dry-run
# Skip firewall configuration
nself prod harden --skip-firewall
# Hardening steps:
# 1. Generate secrets in .env.secrets
# 2. Disable DEBUG mode
# 3. Disable Hasura dev console
# 4. Set log level to warning
# 5. Verify SSL certificates
# 6. Set file permissions (600) on sensitive files
# 7. Configure firewall (unless --skip-firewall)# Run security audit
nself prod check
nself prod audit
# Verbose output
nself prod check --verbose
# Checks performed:
# + DEBUG mode is disabled
# + SSL is enabled
# + No weak/default passwords
# + .env.secrets has secure permissions
# + Required secrets are configured
# + No obvious weak credentials
# + Hasura console disabled
# + Admin UI disabled# 1. Create environments
nself env create dev local
nself env create staging staging
nself env create prod prod
# 2. Configure staging
nself staging init staging.example.com --email admin@example.com
vim .environments/staging/server.json # Add SSH credentials
# 3. Configure production
nself prod init example.com --email admin@example.com
vim .environments/prod/server.json # Add SSH credentials
# 4. Verify SSH access
nself deploy check-access# Switch to staging
nself env switch staging
# Generate/validate secrets
nself staging secrets generate
nself env validate staging
# Build and deploy
nself build
nself staging deploy
# Verify deployment
nself deploy health staging
nself staging logs -f# Validate staging first
nself env diff staging prod
# Switch to production
nself env switch prod
# Harden production
nself prod secrets generate
nself prod ssl request example.com
nself prod harden
# Validate configuration
nself env validate prod --strict
nself prod check --verbose
# Deploy
nself build
nself deploy prod --rolling
# Verify
nself deploy health prod| Component | Staging | Production |
|---|---|---|
| Core Services (PostgreSQL, Hasura, Auth, Nginx) | Always | Always |
| Optional Services (Redis, MinIO, etc.) | If enabled | If enabled |
| Monitoring Bundle | If enabled | If enabled |
| Custom Services (CS_N) | Always | Always |
| Frontend Apps | Included by default | Excluded by default |
| Admin UI | Enabled (debugging) | Disabled (security) |
| Hasura Console | Enabled | Disabled |
# Test SSH connection manually
ssh -i ~/.ssh/deploy_key deploy@server.example.com
# Check key permissions
chmod 600 ~/.ssh/deploy_key
# Verify server.json
cat .environments/staging/server.json
# Test with verbose output
nself deploy staging --check-access# Check remote logs
nself deploy logs
# SSH in and check manually
nself staging shell
docker compose ps
docker compose logs
# Rollback if needed
nself deploy rollback# Check individual services
nself deploy health staging
# View service status
nself staging shell
docker compose ps -a
# Check nginx configuration
docker exec <project>_nginx nginx -t
# View specific service logs
docker compose logs hasura
docker compose logs auth--dry-run before deployingnself env validate before deploy--rollingnself backup create before major updates