ADMIN · BACKUP & RESTORE

Backup & restore

How Meridian's backup model works, what's in a bundle, and how to restore onto a fresh host.

What gets backed up

scripts/backup.sh produces a zstd-compressed tarball with:

The --include-keys decision

TRADE-OFF
Without keys: smaller, safer bundle. Can only be restored onto a host that already has the same master keys (i.e., the same box after a config rollback).
With keys: full DR bundle. Can be restored onto any fresh host. But the bundle now contains the crown jewels — store it with the same care as the source.

Policy recommendation: take routine backups without keys for operational rollback, and take one with-keys backup per significant-change event (master-key rotation, major upgrade, integration cutover). Keep the with-keys bundles offline in secured storage.

Manual backup

# Routine (no keys):
sudo /opt/meridian/scripts/backup.sh

# DR-grade (with keys) — keep this offline:
sudo /opt/meridian/scripts/backup.sh --include-keys

# Custom output location:
sudo /opt/meridian/scripts/backup.sh --output /mnt/offsite/

Automatic backups

Three jobs run without intervention:

WAL archive lives at /var/lib/meridian/backups/wal/ (gzipped per-segment). Adjust retention in Admin → Scheduled Jobs.

Restore

Verify the bundle first (no changes made)

sudo /opt/meridian/scripts/restore.sh --dry-run /path/to/bundle.tar.zst

Full restore

sudo /opt/meridian/scripts/restore.sh /path/to/bundle.tar.zst

The script:

  1. Extracts + verifies the MANIFEST.
  2. Shows what it's about to replace.
  3. Requires you to type RESTORE exactly to confirm.
  4. Stops meridian-app, meridian-celery, meridian-beat.
  5. Drops + recreates the DB, pg_restores with --no-owner --role meridian.
  6. rsyncs etc-meridian/, uploads/, branding/, and (if present) secrets/ back into place.
  7. Starts services and verifies all three stay up.

Restoring onto a fresh host

You need a --include-keys bundle for this. Workflow:

  1. Stand up a new Debian 13 (or 12) host.
  2. Run install.sh with the same portal domain as the source host (so the TLS cert SAN matches).
  3. Copy the bundle onto the host.
  4. sudo /opt/meridian/scripts/restore.sh /path/to/bundle.tar.zst
  5. Log in. Users, audit history, integrations, and branding are all back.

Point-in-time recovery (PITR)

The db-wal-ship job archives WAL segments every 15 minutes. To recover to a specific point:

  1. Identify the target recovery time.
  2. Extract the most-recent full backup from before that time.
  3. Restore the backup normally.
  4. Replay WAL from /var/lib/meridian/backups/wal/ up to the target time using restore_command in recovery.conf.

This is a PostgreSQL-level operation; see the PG docs for specifics. Meridian does not ship a PITR wizard in 1.0.0.

Verifying backup integrity

A bundle that won't restore is worse than useless. Verify monthly:

# Dry-run a random recent bundle:
sudo /opt/meridian/scripts/restore.sh --dry-run \
     /var/lib/meridian/backups/full/meridian-backup-*.tar.zst

For extra confidence, spin up a throwaway test host periodically and perform a full restore onto it.

MERIDIAN 1.0.0 · DOCUMENTATION
meridiannip.com ↗