SIGNALS Documentation
API Reference

Backup and Restore

What to back up on a self-hosted installation, how the update backup works, and the steps to restore onto a new server.

Last reviewed against source:

Signals does not schedule backups for you. Nothing in its scheduled tasks takes a database or file backup, so a self-hosted installation needs its own backup routine. This page covers self-hosted installations.

The only backup Signals takes itself is the pre-update dump described below.


What to back up

Item Why
PostgreSQL database All business data lives here: rentals, invoices, accounts, settings, users and the audit trail. Back up every application schema.
File storage Uploaded attachments, generated documents and exports. With local storage these are under storage/app: the local disk is storage/app/private and the public disk is storage/app/public. With S3-compatible storage, back up the bucket.
.env Holds your connection settings, APP_KEY, SIGNALS_INSTALLED, SIGNALS_SETUP_COMPLETE, SIGNALS_SETUP_PROOF and SIGNALS_INSTALLATION_ID.
APP_KEY Encrypted values in the database and update backups are readable only with the original key. Store a copy separately from the database backup.
SIGNALS_UPDATE_BACKUP_KEY, if you set one When set, update backups are encrypted with it instead of APP_KEY.
Plugins and custom code Keep composer.json and composer.lock in version control so the same release can be installed again.

Everything else, including caches, compiled views and the vendor/ directory, can be rebuilt.

PostgreSQL needs the btree_gist and pg_trgm extensions. If you use AI embeddings it also uses the vector extension. A dump carries the data, so install the same extensions on the restore server first. See Installation.

Back up the database and the files together. Records point to files by path. A database restored without its files, or the reverse, leaves broken links to documents and attachments.


Take a backup

Use your usual PostgreSQL tooling, for example pg_dump -Fc, with the same major version of the client tools as the server. Copy storage/app or snapshot the bucket at the same time. Keep copies on a different machine from the one running Signals, and test a restore regularly into a disposable database.

The update backup

php artisan signals:update takes its own backup before it changes anything. It puts the application into maintenance mode, runs pg_dump -Fc, encrypts the archive into storage/app/update-backups/, and verifies it before installing the new release. Retention defaults to 30 days (SIGNALS_UPDATE_BACKUP_RETENTION_DAYS).

Command Purpose
php artisan signals:update:prune-backups Removes expired update backups. --days= overrides retention; --dry-run lists what would go. The live rollback point is kept.
php artisan signals:update:decrypt-backup {path} --output=FILE Decrypts an update backup so pg_restore can read it. --output must be a new file in an existing directory.
php artisan signals:update:recover --status Shows the state of an interrupted update.
php artisan signals:update:recover --restore Restores the recorded backup after a failed update, once the source release is reinstated.

These commands are unavailable on Signals Cloud. The full recovery procedure is in Updates and Upgrading.

The update backup is a safety net for updates. It is not a replacement for scheduled backups: it holds only the database, and only at the time of the last update.


Restore onto a new server

  1. Install the same Signals release and PHP extensions on the new server. See Installation. Do not run the setup wizard.
  2. Restore .env with its original APP_KEY. Set the database, cache, queue and storage values for the new environment. Keep SIGNALS_INSTALLED=true and SIGNALS_SETUP_COMPLETE=true.
  3. Create an empty PostgreSQL database with the btree_gist and pg_trgm extensions, and vector if the source used it.
  4. Restore the database into it. For a dump you took yourself, use pg_restore as you normally would. For an update backup, decrypt it with signals:update:decrypt-backup first, then follow the worked sequence in Updates.
  5. Restore storage/app, or point the storage settings at the restored bucket.
  6. Clear and rebuild caches, then restart workers: php artisan optimize:clear, php artisan optimize, php artisan queue:restart.
  7. Run php artisan signals:status to check the database, Redis and storage connections.
  8. Restart the scheduler cron entry and the queue workers, as described in Scheduled Tasks. Open Admin → System → System Health and confirm the checks are green.
  9. If the backup is older than live use, tell your team which changes were lost. Everything entered after the backup is gone.

If the restored installation runs a different release from the backup, run php artisan migrate --force and follow Upgrading.

Privacy requests and restores

If your organisation erased or anonymised accounts after the backup was taken, a restore brings that personal data back. Inspect the recorded restore tombstones with:

php artisan signals:privacy:reapply-tombstones --dry-run

Running it without --dry-run opens draft privacy cases for human verification and approval. It needs the original encryption key. If the key, the tombstone integrity or the acting user fails its check, the command refuses and commits no cases. See Accounts.

If you restore without .env

The setup pages return 404 once any user exists, even if SIGNALS_SETUP_COMPLETE was lost with the old .env. Rebuild .env from your copy rather than running setup again.


signals:reset removes data

Danger. php artisan signals:reset is not a backup or restore tool. It permanently deletes documents, document sequences, settings, warehouses and users, then sets SIGNALS_SETUP_COMPLETE=false. It does not undo itself and does not guarantee that setup can run again afterwards.

--force is required, and production also needs --allow-production-reset. Run it with --dry-run first to see row counts without changing anything, and take a verified backup before any real run. Details are in Configuration.


Reference Use it for
Updates Update backups, recovery and the worked manual restore
Upgrading Preparing and running an upgrade
Storage Where uploaded files are held
Configuration Setup, reset and ownership guards