Skip to main content
Version: 0.1

Backup and restore

This page is for administrators. A backup is a consistent copy of the gateway's SQLite database. A restore is staged: the file is checked now and swapped in the next time the gateway starts, and the database it replaces is kept. Nothing here deletes data.

What the database holds​

The gateway database (scadex.db in DATA_DIR) holds settings, users, API keys, sign-in providers, tags and tag types, screens and start screens, alarms and their history, database connections and storage routes, event streams, pipelines, modes, reports, the write audit log, and each module's state (connections and settings, encrypted).

What a backup does not contain​

warning

A backup is the database only. Keep these beside it, or the restore is incomplete:

  • DATA_DIR/keys, the Data Protection keys. Module state (driver passwords), database passwords and identity provider secrets are encrypted with them. A database restored without its keys cannot decrypt that state: the module that owns it reports failed with an error saying so, database connections cannot sign in, and provider sign-ins fail. Back up DATA_DIR/keys with the database, ideally to somewhere else.
  • Licences and module files in the modules directory.
  • Module data: each module's own directory, such as the historian's history.db and the cron module's runs.db. History is not in the backup.
  • DATA_DIR/modules.json (remembered log levels and stopped modules) and the module log files under DATA_DIR/logs.
  • The event backbone's JetStream data (recent values for replay).

The Backup and restore page​

Open Gateway, then System, then Backup & restore. Anyone who is not an administrator sees "Only administrators can back up or restore the gateway."

Downloading a backup​

Click the download button. The gateway makes a consistent copy of the database while it runs (VACUUM INTO a temporary file in DATA_DIR/backups) and sends it as scadex-backup-<yyyyMMdd-HHmmss>.db; the temporary file is deleted once sent. Your browser saves it when it is ready. Download a fresh one before any change you might want to undo.

Restoring​

  1. Click the restore button and choose a .db file.
  2. The gateway checks it now: it must start with the SQLite header, pass PRAGMA integrity_check, and contain the tables User, Tag and AppSetting. A file that fails answers 400 with "That isn't a gateway backup." or "The backup is damaged."
  3. The file is staged as DATA_DIR/restore-pending.db. The page shows that a restore is waiting, with the time it was staged, and offers Cancel restore.
  4. Restart the gateway by hand. The page does not restart it.
  5. At the next start, before anything opens the database, the gateway moves the current database to DATA_DIR/backups/pre-restore-<yyyyMMdd-HHmmss>.db, deletes its -wal and -shm files, and moves the staged file into place. The console logs "Restored the staged backup. The previous database was kept as backups/…".

A staged file that no longer validates at start is left alone rather than swapped in. Uploads are limited to 512 MB.

note

Every session is tied to the database, so after a restore everyone signs in again, and users, keys and screens are as they were when the backup was taken. The audit log and alarm history revert too. Module data outside the database (history, cron runs) does not revert.

Cancelling​

Cancel restore deletes the staged file. The gateway keeps its current database.

Limits​

  • Manual only: no schedule, no retention of old backups, no off-site copy. Old databases in DATA_DIR/backups are never deleted by the gateway.
  • Database only; see the list above.
  • The restore needs a restart you perform yourself (for example docker compose restart).

API​

All routes need the admin role. The full reference is in Admin API.

RoutePurpose
GET /api/v1/admin/backupDownload a consistent copy of the database
GET /api/v1/admin/restore{pending, stagedAt}: whether a restore waits for the next start
POST /api/v1/admin/restoreStage a restore; the raw request body is the .db file. 202 {pending: true} or 400
DELETE /api/v1/admin/restoreDrop the staged restore
curl -H "Authorization: Bearer scx_..." -o scadex-backup.db https://app.scadex.io/api/v1/admin/backup

An API key cannot be an administrator, so a scripted backup needs a signed-in session's cookie rather than a key.