Appearance
nkapp backup / restore
Nanokit's backup system provides manual and automatic database backups for self-hosted databases, local filesystem storage, and S3-compatible object storage.
Managed provider-snapshot backups (e.g. Neon) are planned (roadmap.v3) and not selectable today — see Providers → Roadmap.
Usage
bash
# Take a manual backup
nkapp backup [database] [options]
# List the backup catalog
nkapp backup list [options]
# Restore from a backup
nkapp restore <database> --backup <id|latest> --in-place [options]Commands
nkapp backup [database]
Take a manual backup of a database. When [database] is omitted, defaults to the first configured database in nanokit.yml.
bash
nkapp backup app -e production
nkapp backup app -e production --note "before schema migration"Options:
| Flag | Type | Default | Description |
|---|---|---|---|
-e, --env <env> | string | local | Target environment |
--note <text> | string | — | Optional label stored alongside the backup metadata |
--trigger <kind> | manual | auto | pre-deploy | manual | How the backup is recorded in the catalog |
On success, prints the backup ID, compressed size, and storage location.
For a remote environment the dump streams from the remote database container over SSH — nothing is written to the remote host.
nkapp backup list
List the backup catalog for an environment, newest first.
bash
nkapp backup list -e production
nkapp backup list -e production --database appOptions:
| Flag | Type | Default | Description |
|---|---|---|---|
-e, --env <env> | string | local | Target environment |
--database <db> | string | — | Filter to a specific database name |
It reads the local catalog index directly, so no SSH or target connection is needed — remote environments can be listed offline.
nkapp restore <database>
Restore a database from a backup.
bash
nkapp restore app --backup latest --in-place -e production
nkapp restore app --backup bk_20260613_030012 --in-place -e production -yOptions:
| Flag | Type | Default | Description |
|---|---|---|---|
--backup <id|latest> | string | latest | Backup ID to restore |
-e, --env <env> | string | local | Target environment |
--in-place | boolean | false | Currently required. Overwrite the live database in place |
-y, --yes | boolean | false | Skip confirmation prompt |
Safety: before overwriting the database, restore automatically takes a pre-restore safety backup so you can undo the restore if needed.
Phase 1 — --in-place is the only mode, and it is not the default
Omitting --in-place does not fall back to anything: the command errors out and tells you to pass it. Restoring into a new, isolated database branch is planned but not yet available.
Only postgres and mongo can be restored today
nkapp restore fails fast for engines whose restore is not implemented — mysql, mariadb and redis are rejected with a clear error before any safety backup is taken, so an unsupported engine pays for nothing. Backups for those engines still work; only the restore path is missing.
Backup Mechanism
The mechanism is selected per-database based on the engine and provider:
| Engine / Provider | Backup | Restore |
|---|---|---|
| PostgreSQL (self-hosted) | pg_dump, gzip-compressed | ✅ pg_restore |
| MongoDB | mongodump | ✅ mongorestore |
| MySQL | mysqldump | ⛔ not implemented |
| MariaDB | mysqldump | ⛔ not implemented |
| Redis | redis-cli --rdb dump | ⛔ not implemented |
| Neon (managed Postgres) | provider snapshot | planned (roadmap.v3) — engine not selectable today |
All dump-based backups are:
- gzip-compressed before storage.
- SHA-256 checksummed — the checksum is verified before any restore is applied.
- Optionally age-encrypted (see
encryptionconfig below).
Storage Targets
Backups can be stored on the local filesystem (default) or an S3-compatible object store.
| Target | Description |
|---|---|
local | .nanokit/backups/ in the project directory |
s3 / spaces / r2 / gcs / minio | AWS S3, DigitalOcean Spaces, Cloudflare R2, GCS, or any MinIO-compatible endpoint |
Credentials resolve in layers: inline fields → a credentials string (env://ACCESS:SECRET or a literal access:secret) → standard environment variable pairs (AWS_*, MINIO_*, S3_*). A non-AWS endpoint with no resolvable credentials fails fast rather than attempting an anonymous upload.
Configuration (nanokit.yml)
Backup Targets
Define one or more named storage destinations at the top level:
yaml
backupTargets:
primary:
type: s3 # local | s3 | spaces | r2 | gcs | minio
bucket: nk-backups
region: eu-south-1
prefix: my-project
# For non-AWS S3-compatible stores, supply an endpoint:
# endpoint: https://nyc3.digitaloceanspaces.com
# Credentials are read from the environment or a vault:// reference —
# never put plaintext secrets in nanokit.yml.
# AWS S3: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
# DO Spaces: SPACES_ACCESS_KEY / SPACES_SECRET_KEYPer-Database Backup Config
yaml
databases:
app:
engine: postgres
backup:
enabled: true
target: primary # references a key in backupTargets
mechanism: dump # dump | both (snapshot is neon-only — planned, roadmap.v3)
schedule: "0 3 * * *" # cron expression — automatic scheduled backups
retention:
keep_last: 7 # keep the N most recent backups
min_keep: 3 # always keep at least this many regardless of age
encryption:
mode: age
key: vault://secret/nk/backup-key # never inline the key
preDeploy: true # take a backup before every nkapp deploy / upAn explicit backup.mechanism wins over the engine default; both currently degrades to dump with a warning.
Full Example
yaml
backupTargets:
primary:
type: s3
bucket: nk-backups
region: eu-south-1
prefix: my-project
databases:
app:
engine: postgres
backup:
enabled: true
target: primary
mechanism: dump
schedule: "0 3 * * *"
retention: { keep_last: 7, min_keep: 3 }
encryption: { mode: age, key: vault://secret/nk/backup-key }
preDeploy: true
cache:
engine: redis
backup:
enabled: true
target: primary
mechanism: dump
# Note: redis restore is not yet available (see Limitations)Backup Modes
Manual
Use the nkapp backup and nkapp restore commands to trigger backups and restores on demand (see Commands above).
Automatic — Scheduled (schedule)
When a schedule cron expression is set, Nanokit runs backups on that cadence. Retention rules (keep_last / min_keep) are applied after each scheduled run.
Automatic — Pre-Deploy (preDeploy: true)
When preDeploy: true is set, Nanokit takes a backup of the database before the reconcile phase of nkapp deploy or nkapp up. This gives you a safe rollback point before schema migrations or service changes are applied.
Under a partial deploy scope the pre-deploy backup set is narrowed to the databases the in-scope services actually touch.
Hub Integration
All backup operations are also available in the Hub → Backups panel:
- Browse the full backup catalog with metadata (size, timestamp, note, checksum status).
- Backup now button — triggers a manual backup for any configured database.
- In-place restore — select a backup and restore with a single click (same safety-backup flow and the same engine guard as the CLI).
- Last-backup-age indicator — at-a-glance freshness status per database.
- Per-database backup config and backup-target management UI.
Limitations (Phase 1)
The following are known limitations of the current implementation:
- Restore is in-place only, and
--in-placemust be passed explicitly. Restore into a new isolated database branch is planned. - MySQL / MariaDB restore is not implemented. Backups are taken normally; restoring must be done manually (e.g. via
nkapp shell -d). - Redis restore is not implemented. Dump (snapshot export) works.