Disaster recovery operations: create and manage backups, restore from a snapshot, inspect your DR plan, run drills, and audit backup coverage. Your data is only safe if restoration has been tested.
# Create a backup now
nself dr backup
# Check backup status
nself dr status
# Restore from the latest backup
nself dr restore --latest
# Run a DR drill (non-destructive restore simulation)
nself dr drillnself dr <SUBCOMMAND> [FLAGS]nself dr is the CLI interface for the nSelf disaster recovery system. It covers the full DR lifecycle: creating encrypted backups, restoring from a specific snapshot, viewing your documented recovery plan, checking the health of scheduled backup jobs, running a dry-run drill to verify restoration works, and auditing backup coverage gaps.
Backups are stored at the destination configured in your NSELF_BACKUP_DEST env var (local path, S3-compatible bucket, or Hetzner Storage Box). They are encrypted with age encryption using the key at NSELF_BACKUP_KEY.
The weekly R2 snapshot cron is managed by nself dr backup scheduled via nself schedule. Use nself dr status to verify that the cron is running and recent snapshots exist.
Create an encrypted snapshot of the database, volumes, and config.
# Create a full backup
nself dr backup
# Backup a specific environment
nself dr backup --env prod
# Backup to a specific destination
nself dr backup --dest s3://mybucket/nself-backups/
# Output:
# ✓ Dumping PostgreSQL (np_* tables)...
# ✓ Archiving volumes...
# ✓ Encrypting with age key...
# ✓ Uploading to s3://mybucket/nself-backups/2026-05-07-14-22.tar.age
# ✓ Backup complete (247 MB, 14s)Restore from a backup snapshot. Prompts for confirmation before overwriting data.
# List available snapshots, then restore one
nself dr restore --list
nself dr restore 2026-05-07-14-22
# Restore the most recent snapshot
nself dr restore --latest
# Restore to a specific environment
nself dr restore --latest --env staging
# Skip confirmation (CI use only)
nself dr restore --latest --yesDisplay the documented DR plan for this installation, including RTO/RPO targets and recovery steps.
nself dr plan
# DR Plan: nself.org production
# ─────────────────────────────
# RTO target: 1 hour
# RPO target: 24 hours (daily backup cron)
# Primary backup: s3://nself-backups/prod/ (Hetzner Object Storage)
# Encryption: age (key in ~/.nself/backup.key)
# Last drill: 2026-04-14 (passed)
# Next drill due: 2026-07-14
# Recovery steps: nself dr restore --latest && nself start && nself doctor --deepShow backup job status, last snapshot time, storage usage, and schedule health.
nself dr status
# Last backup: 2026-05-07 02:00 UTC (14h ago)
# Snapshot count: 30 (30-day retention)
# Storage used: 7.2 GB (s3://nself-backups/prod/)
# Backup schedule: Daily at 02:00 UTC (next: 2026-05-08 02:00 UTC)
# Schedule status: ✓ healthy
# Oldest snapshot: 2026-04-07
# Encryption: ✓ age key presentRun a non-destructive restore simulation: download the latest snapshot, decrypt it, and verify integrity — without overwriting the live database. Produces a drill report.
nself dr drill
# Downloading latest snapshot (2026-05-07-02-00.tar.age)...
# Decrypting...
# Verifying archive integrity...
# Test-importing to temporary Postgres instance...
# ✓ All np_* tables present (47 tables)
# ✓ Row counts match pre-backup telemetry
# ✓ Drill passed in 4m 22s
# Drill report: /tmp/nself-dr-drill-2026-05-07.jsonAudit backup coverage: identify tables, volumes, or services not included in the current backup config.
nself dr audit
# Tables in backup: 47 / 47 np_* tables ✓
# Volumes in backup: 3 / 4 volumes
# ✗ nself_minio_data — not included in backup config
# Custom services: 1 / 1 CS_N services ✓
#
# Coverage: 98% — 1 gap found| Flag | Type | Default | Description |
|---|---|---|---|
--env | string | current | Target environment (local, staging, prod) |
--dest | string | Override backup destination (path or S3 URL) | |
--latest | bool | false | Use the most recent snapshot (restore) |
--list | bool | false | List available snapshots (restore) |
--yes | bool | false | Skip confirmation prompts (restore) |
--json | bool | false | Output as JSON |
--retention | int | 30 | Days of snapshots to keep (backup) |
| Variable | Description |
|---|---|
NSELF_BACKUP_DEST | Backup destination (local path or s3://bucket/prefix/) |
NSELF_BACKUP_KEY | Path to age encryption key for backups |
NSELF_BACKUP_RETENTION | Number of days to retain snapshots (default: 30) |
AWS_ACCESS_KEY_ID | S3-compatible access key (Hetzner, AWS, Cloudflare R2) |
AWS_SECRET_ACCESS_KEY | S3-compatible secret key |
AWS_ENDPOINT_URL | S3-compatible endpoint (required for non-AWS providers) |
# Schedule a daily backup at 02:00 UTC
nself schedule create "nself dr backup --env prod" --cron "0 2 * * *" --name "daily-dr-backup"# Backup prod
nself dr backup --env prod
# Restore that snapshot to staging
nself dr restore --latest --env stagingnself dr drill --json > drill-$(date +%F).json
# Archive the report for compliance records0 — operation succeeded1 — backup or restore failed2 — snapshot not found or decryption failed3 — invalid arguments or missing subcommand