Skip to main content

Back up and restore an on-premise installation

An on-premise Rational AI installation keeps its data in several places: a PostgreSQL database, a vector store, an object storage, the installed extensions and the knowledge databases. Settings → Backup copies all of them, in one run, to a destination you own — a network share, an S3 bucket, an FTP or SFTP server, or a mounted folder — on a daily schedule or on demand. This guide covers what a backup contains, how to set the destination up, how to check that backups are really happening, and the offline procedure that brings an installation back from one.

📖ON-PREMISE ONLY

The Backup page exists only where the installation is configured for it (Backup__Enabled=true on the backend, see Prerequisites). On the managed cloud the platform backs the data up for you and the page is not shown.

The Backup page in Settings, with a network-share destination, a daily schedule and one backup listed

What a backup contains​

ComponentWhat is capturedHow
postgresEvery database on the server: the application data of every tenant, the workflow engine, the identity provider. This is also where the key ring that protects stored credentials lives, so a backup is sensitive material — keep the destination as private as the installation itself.One pg_dump per database plus the roles, streamed to the destination
qdrantThe vector collections (embeddings behind knowledge retrieval)One snapshot per collection, streamed to the destination and removed from the vector store afterwards
storageThe object storage: attachments, synced source files, extension packagesAn incremental mirror in the storage/ folder of the destination, shared by every backup
extensionsThe installed extensions directoryA tar.gz per backup
sqldThe knowledge databases (Rational BI, SQLite resources)A tar.gz per backup

Each run produces a folder named after its UTC start time (2026-09-09T02-30-00Z) with a manifest.json describing what it holds. The object-storage mirror is never pruned: files deleted from the application stay in the mirror, so every dump — old or new — finds the attachments it references. Retention only removes whole backup folders.

📝WHAT IS NOT BACKED UP

Downloaded models (Ollama, Hugging Face), the audio model cache and the Python package caches are not part of a backup: they are re-downloaded on demand after a restore. The session cache is not backed up either; after a restore everyone signs in again.

Prerequisites​

Before you start, make sure you have:

  • Administrative access. The page is admin-gated.

  • Backup enabled on the installation. The backend needs Backup__Enabled=true, and the worker that performs the backup (temporal-worker) needs to know where the live data is:

    VariableValue on a Compose installation
    BACKUP_POSTGRES_URLpostgresql://postgres:<password>@db:5432/postgres
    BACKUP_QDRANT_URLhttp://vectordb:6333 (plus BACKUP_QDRANT_API_KEY if one is set)
    BACKUP_EXTENSIONS_PATHThe extensions directory, mounted into the worker (for example ./data/extensions:/rationalai/backend/extensions)
    BACKUP_SQLD_PATHThe libsql data directory, mounted into the worker (for example ./data/sqld:/backup/sqld)

    The object storage needs nothing extra: the worker already reaches it as its dest: rclone remote. A component whose variable is missing is reported as skipped, not as a failure.

  • A destination with enough space for the database dumps, the vector snapshots and a full copy of the object storage. The worker itself needs no free disk: everything is streamed.

Set the destination​

Go to Settings → Backup and pick the destination Type. The fields change with the type:

TypeFieldsPath
Network share (SMB / Samba)Host, port (445), user, password, domainShare and folder, e.g. backups/rational
S3 bucketEndpoint, provider (Other for a NAS or MinIO, AWS for Amazon), region, access key ID, secret access keyBucket and prefix, e.g. my-bucket/rational
FTP serverHost, port (21), user, passwordFolder
SFTP serverHost, port (22), user, passwordFolder
Local folder (NFS mount)—The absolute path of a folder the worker can see, typically an NFS mount added to the worker container

The folder is created on first use. Click Test destination before saving: the worker writes and deletes a small marker file there, which proves the credentials, the path and the write permission in one go. A failure comes back with the reason (a wrong password, a read-only share, an unreachable host).

⚠️PREFER SFTP OR S3 OVER FTP

Plain FTP sends the password and the data in clear and cannot verify what it wrote. It is supported for legacy targets; when the same server offers SFTP, use that.

Passwords and access keys are stored encrypted. When you come back to the page they show as ********; leave them as they are to keep the stored value, or type a new one to replace it.

Schedule​

Daily backup runs a backup every day at the Time of day shown, in the time zone of your browser at the moment you save. A run that is still going when the next one is due is not interrupted; the next one is skipped.

Retention​

After each successful run the destination is pruned. A backup stays when any rule keeps it; everything else is removed. Zero switches a rule off, and at least one rule must be set.

RuleKeeps
Most recent backupsThe newest N backups, whatever their age
One per day, for daysThe newest backup of each day, for the last N days
One per week, for weeksThe newest backup of each week, for the last N weeks
One per month, for monthsThe newest backup of each month, for the last N months

A typical policy is 7 most recent, one per week for 8 weeks, one per month for 12 months: a week of daily restore points, two months of weekly ones, a year of monthly ones — roughly 27 backups at the destination instead of 365. Only the dumps and snapshots are pruned; the object-storage mirror is shared by every backup and is never removed.

Click Save. The Next scheduled backup line under Last backup confirms the schedule is registered.

Back up now, and check it happened​

Back up now starts a backup immediately. While it runs the page shows each component as it is captured; when it finishes, Last backup shows the time, the outcome, the size and the folder name, and the backup appears under Backups at the destination.

A failed run reports the error in place of the size. A backup that fails half-way is removed from the destination, so whatever is listed there is complete and restorable.

Two things are worth checking now and then:

  • Last backup keeps moving and says completed. A schedule nobody watches is a schedule that can silently stop.
  • The list under Backups at the destination is what the destination actually holds, read from it each time the page loads — not a log kept by the application. If the destination disappears, so does the list.

Restore​

Restoring replaces the current data with a backup, which is why it is not a button: the application must be stopped while its databases are dropped and recreated. It runs from a shell on the host, with the same worker image, using the command the page gives you.

🛑A RESTORE OVERWRITES EVERYTHING

Every database, the vectors, the object storage, the extensions and the knowledge databases are replaced by the backup's contents. Anything created after that backup was taken is lost. Take a fresh backup first if there is any doubt.

  1. In Backups at the destination, click Copy restore command on the backup you want. The command carries the destination settings as environment variables; the secrets are masked as ******** — replace them with the real values.

  2. On the host, stop every application service but keep the data services running:

    docker compose stop backend fastapi-proxy temporal-worker temporal keycloak webserver

    db, vectordb, s3 and sqld stay up: the restore writes into them.

  3. Run the copied command. It looks like this:

    docker compose run --rm --no-deps \
    -e RCLONE_CONFIG_BACKUP_TYPE=smb \
    -e RCLONE_CONFIG_BACKUP_HOST='nas.example.com' \
    -e RCLONE_CONFIG_BACKUP_USER='backup' \
    -e RCLONE_CONFIG_BACKUP_PASS='<the password>' \
    -e BACKUP_ROOT='backup:backups/rational' \
    temporal-worker rational-backup restore 2026-09-09T02-30-00Z

    It asks for confirmation, then restores the roles and databases, syncs the object storage back, uploads the vector snapshots and unpacks the extensions and the knowledge databases, printing one line per step. Add --yes to skip the confirmation, --only postgres,qdrant to restore a subset.

  4. Start everything again:

    docker compose up -d
  5. Sign in and check a recent conversation, a knowledge base and an extension. Extensions may take a moment on first use while their packages are re-downloaded.

A few consequences to know about:

  • The database superuser password is not changed by the restore, even though the backup carries the old one, so the .env that drives your Compose stack keeps working.
  • Everyone is signed out: sessions are not part of a backup.
  • The backup includes the workflow engine's state. A backup run that was in progress when that backup was taken may resume and complete after the restore; it is harmless.
  • Restore into the same version of Rational AI that took the backup, or a newer one: the application migrates the database forward on start, never backwards.

Rehearse it​

A backup that has never been restored is a hope, not a plan. The same command restores into a spare installation — a second Compose stack on another host, or the same one with fresh volumes — without touching production. Doing this once after setting the destination up, and again after upgrades, is the only way to know the destination is really usable.

The worker also offers rational-backup list, show <name> and probe with the same environment variables, for scripts and for checking a destination from the shell.

Troubleshooting​

SymptomLikely cause
Test destination fails with permission deniedThe share or folder is read-only for the given user.
The status shows failed with pg_dump: server version mismatchThe worker image is older than the database server; update the worker.
A component is skippedIts BACKUP_* variable is not set on the worker, or the path it points at does not exist there.
The backups list is empty though runs completedThe destination path was changed after those runs: the list reads the current path.
The restore stops at database … restored with is being accessed by other usersAn application service is still connected. Stop it and run the command again.