Skip to content

Backup and Restore

Create and restore install-directory backups of SafeCall data.

safecall app backup

Creates a timestamped backup under {install_dir}/backups/.

Usage

bash
sudo ./util.sh app backup
sudo ./util.sh app backup --dir backups
sudo ./util.sh app backup --dry-run

Behavior highlights

  • Creates {install_dir}/backups/YYYY-MM-DD_HHmmss/ with:
    • metadata.txt — JSON metadata
    • core.tar.gz — database snapshots, config, and small text files
    • assets.tar.gz — maps and bug-screenshots, or a symlink to a prior identical archive
  • Uses online SQLite backup (VACUUM INTO) so the service can keep running.
  • Excludes logs/ and the backups/ directory itself.
  • Reuses prior assets.tar.gz via symlink when map/image content is unchanged.

safecall app bugs sync

Posts unsynced local bug reports (and their comments) to the central bug collector.

Usage

bash
sudo ./util.sh app bugs sync

Behavior highlights

  • No-ops when server_bug_tracker_enabled is false, or when collector URL/secret is empty.
  • Creates each report on the collector once (multipart with screenshot), then marks synced_at.
  • Every run posts lightweight POST /v1/status for still-open reports so GitLab can be reopened if needed.
  • When a report is marked fixed locally, posts fixed status once, stores last_synced_status=fixed, and does not send again unless reopened.
  • Sends new comments afterward (reopens closed GitLab issues on the collector side).
  • Installed daily at 16:00 via safecall integrations cron (0 16 * * *).

Configure server_bug_collector_url and server_bug_collector_shared_secret (URL defaults from the brand for SafeCall).

safecall app restore

Restores database, config, and assets from a backup directory.

Usage

bash
sudo ./util.sh app restore
sudo ./util.sh app restore --from backups/2026-07-08_000000
sudo ./util.sh app restore --yes

Behavior highlights

  • Defaults to the latest backup in {install_dir}/backups/.
  • Stops the SafeCall service before restore and starts it afterward.
  • Runs selftest after restore unless --skip-selftest is passed.
  • Prompts for confirmation unless --yes is passed.
  • If the destination already has .service_name, restore keeps that identity instead of the backup's (so a clone cannot take over the source systemd unit).
  • If {install_dir}/.instance_overlay.json exists, its keys are merged into config/main.config.json after extract. Keep this file at the install root (not under config/) so backups do not overwrite it.

Clone another instance (refresh a parallel install)

bash
sudo /opt/safecall/util.sh app backup   # optional fresh snapshot
LATEST=$(ls -1d /opt/safecall/backups/20* | tail -1)
cd /opt/safecall-sourcectl
sudo ./util.sh app restore --from "$LATEST" --yes --skip-selftest

Example overlay for a test instance that must stay on a different port and must not page production ntfy:

json
{
  "server_http_port": 8089,
  "server_ntfy_enabled": false,
  "server_ntfy_ops_enabled": false,
  "server_bug_tracker_enabled": false,
  "server_features": ["safecall"]
}

--from accepts an absolute path, so the backup can live in the other instance's backups/ directory. After restore, confirm .service_name and server_http_port still match this instance.

When to use

  • Disaster recovery on a production install.
  • Rolling back config/database/assets after a bad change.
  • Verifying backup integrity in a staging environment.
  • Refreshing a parallel install from production without changing that install's service name or port.

Web UI (admin)

Admins can manage backups from System → Backup (/backup):

  • Create backup — runs the same online backup as safecall app backup
  • List / download — download a portable .tar.gz (assets are dereferenced, not symlinked)
  • Upload — import a previously downloaded backup bundle onto the server
  • Restore — type RESTORE to confirm; the server schedules a CLI restore that stops the service, restores files, then starts the service again (brief downtime)

Restore from the UI skips selftest (--skip-selftest). Run safecall app selftest afterward if you need the full post-restore checks.