Backup & restore

Back up and restore Leoflow state — metadata, secrets, and logs.

Lite ships two commands that snapshot and re-load the whole install in one portable file: leoflow lite backup and leoflow lite restore. Use them to migrate to another machine, survive an OS reinstall, or roll back a botched upgrade.

What is included

A backup archive (leoflow-backup-<timestamp>.tar.gz) contains:

File / dirContents
MANIFEST.jsonFormat version, leoflow_version, embedded schema version, Postgres version, created_at
config.yamlThe admin email + password hash, JWT signing secret, parser command, workspace path
setup.jsonSetup metadata (Python interpreter, OS/arch)
datastore.sqlA logical pg_dump (–clean –if-exists, plain SQL) of the managed Postgres — DAGs, runs, task instances, XCom, Variables, Connections
workspace/Your project tree (DAGs, leoflow.yaml, etc.). VCS dirs and virtualenvs are excluded (see below)

What is not included:

  • ~/.leoflow/python/ (managed CPython) — re-fetched by leoflow setup on the target machine if needed.
  • ~/.leoflow/postgres/ (managed PG binaries) — same.
  • ~/.leoflow/venv/ (parser/runtime venv) — re-installed lazily.
  • VCS metadata (.git, .hg, .svn).
  • Build artifacts (.venv, venv, __pycache__, .pytest_cache, node_modules, .tox, .mypy_cache).

The trade-off: backups are small and portable (the heavy stuff is what the binary can fetch back), and they will not silently leak .git/ history a user committed locally but did not push.

Backup

# Default: leoflow-backup-<UTC-timestamp>.tar.gz in the current directory.
leoflow lite backup

# Custom output path:
leoflow lite backup --output ~/snapshots/before-upgrade.tar.gz

backup requires Lite to be running (it talks to the managed Postgres via its socket to capture a consistent dump). Run leoflow lite in another terminal first.

Restore

# Refuses to overwrite an existing ~/.leoflow install:
leoflow lite restore --input ~/snapshots/before-upgrade.tar.gz

# Use --force to overwrite explicitly (e.g. after `leoflow uninstall`):
leoflow lite restore --input ~/snapshots/before-upgrade.tar.gz --force

The restore command refuses, with a clear error, when:

  1. The archive’s schema is newer than this binary supports — refusing the restore is the inverse of the upgrade-time drift detector (see Upgrades). Loading rows into a DB the binary cannot read would corrupt them.
  2. ~/.leoflow/ already holds an install and --force is not set. Pass --force only after confirming you want to overwrite.
  3. The archive’s MANIFEST.json is missing or carries a manifest_version newer than this binary understands.

--force does not silence the schema-drift refusal. Corruption is not opt-in.

Worked example: migrate to a new machine

# On the source machine (Lite running):
leoflow lite backup --output /tmp/snap.tar.gz
scp /tmp/snap.tar.gz user@new-host:~/

# On the new machine, after `curl ... install.sh`:
leoflow setup           # provisions managed Python + binaries
leoflow lite restore --input ~/snap.tar.gz
leoflow lite            # boots with the restored datastore + workspace

Worked example: roll back a botched upgrade

# Before upgrading: take a snapshot.
leoflow lite backup --output ~/snap-before-upgrade.tar.gz

# Upgrade (re-run install.sh, restart leoflow lite). Something breaks.

# Wipe and restore. --purge removes the new install completely; restore
# refuses without it because ~/.leoflow is non-empty after the upgrade.
leoflow uninstall --purge
# Re-install the previous version's binaries via install.sh's pin, then:
leoflow lite restore --input ~/snap-before-upgrade.tar.gz
leoflow lite

Pro (Pro)

The Helm-installed Pro control plane does not ship its own backup/restore commands. Pro operators own the Postgres backup story via standard tooling:

  • Managed Postgres providers (RDS, Cloud SQL, etc.) offer point-in-time recovery and automated snapshots.
  • Self-hosted Postgres: use pg_dump / pg_dumpall on a cron + an offsite archive (S3, GCS).
  • Persistent volumes: capture via Velero or your cluster’s volume snapshot controller.

The PR that hardens the Helm chart (#96) will add a BACKUP.md to the chart README pointing at the upstream guidance.

  • #137 — these commands.
  • #136 — upgrade contract (the safety guard inside restore mirrors the drift detector at startup).
  • #150 — CI smoke that exercises a full backup → upgrade → restore cycle end-to-end.