Skip to content

Backup & Restore

Orimora includes an automated backup system that creates daily database dumps and weekly Markdown exports.

Add the following environment variables to your .env file:

Terminal window
BACKUP_ENABLED=true
BACKUP_PATH=/backups/orimora
BACKUP_RETENTION_DAILY=7
BACKUP_RETENTION_WEEKLY=4
BACKUP_SCHEDULE=0 3 * * *
VariableDescriptionDefault
BACKUP_ENABLEDEnable automated backupstrue in prod
BACKUP_PATHDirectory for backup files (local, plaintext)/backups/orimora
BACKUP_RETENTION_DAILYDaily DB dumps to keep7
BACKUP_RETENTION_WEEKLYWeekly Markdown exports to keep4
BACKUP_SCHEDULECron expression (UTC)0 3 * * *
BACKUP_S3_BUCKETParsed but not wired up — for S3-compatible off-site, use BACKUP_RCLONE_REMOTE (rclone reaches S3 targets)unset
BACKUP_RCLONE_REMOTErclone remote path for encrypted off-site copies (S3-free)unset
BACKUP_POST_HOOKCommand run with each egress artifact path (targets rclone can’t reach)unset
BACKUP_PG_DUMP_TIMEOUT_MSpg_dump timeout (ms) — raise for multi-GB databases300000 (5 min)

A full PostgreSQL dump using pg_dump --format=custom. This is the primary backup method and captures all data including documents, users, settings, and metadata.

Every Sunday, Orimora exports all collections as ZIP files containing Markdown files with YAML frontmatter. These are human-readable and can be imported into other systems (including Obsidian).

Attachments are archived to uploads-<ts>.tar.gz alongside the database dump, so a single restore brings back documents and their images.

When STORAGE_DRIVER=s3, uploads live in your bucket, not on local disk, so Settings → Admin → Backups shows an Uploads backup choice:

  • Provider-managed (default) — back up the bucket via its own versioning / replication. Orimora skips the uploads archive (and says so in the log) rather than writing an empty one.
  • Replicate into backups — Orimora downloads the whole bucket on each run into the uploads archive, so the same encryption + off-site pipeline covers it. Heavier (per-run egress); best for small buckets, or to keep a copy outside your S3 provider.

Sessions and queues are ephemeral — not part of the backup set. Users simply re-login after a restore, and the BullMQ backup scheduler re-registers itself on boot. No Redis restore is needed.

This is the part that turns “I have a dump on the same box” into real disaster recovery. Without an off-site, encrypted copy, a host loss or ransomware event loses everything.

Off-site copies and the in-app download button are encrypted with age. At setup, Settings → Admin → Backups shows the recovery code (an AGE-SECRET-KEY-… private key) once.

Set BACKUP_RCLONE_REMOTE to an rclone remote and Orimora replicates each encrypted artifact off-host. rclone supports SFTP, Backblaze B2, WebDAV/Nextcloud and dozens of S3-free backends — configure it in-app under Settings → Admin → Backups, or via rclone config. Recipes and the safest “pull from a hardened backup host” pattern are in the Disaster Recovery runbook.

Navigate to Settings → Admin → Backups to:

  • View current backup status and health
  • Browse backup history
  • Manually trigger a backup
  • See and copy the recovery code (shown once at setup)
  • Configure the off-site destination (rclone remote) and run a connectivity test
  • Verify the latest backup (a non-destructive integrity check) and follow the guided restore instructions
Terminal window
# Stop the application
docker compose stop app
# Restore the database
pg_restore --clean --if-exists --dbname=knowledgebase /backups/orimora/orimora-db-TIMESTAMP.dump
# Restore uploads
rsync -av /backup-source/uploads/ /app/uploads/
# Restart
docker compose up -d app

Import a Markdown ZIP file via Settings → Collection → Import.

Use the built-in revision history to restore any previous version of a document.

The system alerts when the last successful backup is older than 48 hours. Use the status API for external monitoring:

Terminal window
GET /api/admin/backup.status

Returns healthOk: true/false and details about the last backup.

MetricTargetDriven by
RPO (max data loss)24 hDaily backup at 03:00 UTC (BACKUP_SCHEDULE)
RTO (max outage)4 hManual restore + boot, with the runbook in hand

For the full step-by-step recovery (decrypt → pg_restore → uploads → boot), failure scenarios, off-site rclone recipes, and the monthly drill checklist, see the Disaster Recovery runbook.