staqlydocs

Backup & restore

Take a consistent backup of your staqly data while it runs, and restore it when you need to.

Edit on GitHub

Everything staqly knows (posts, channels, schedules, history, settings and uploaded files) lives in one data directory. Back it up regularly, and always before an upgrade. Backups are taken while staqly keeps running; restoring needs a short stop.

With STORAGE_DRIVER=s3 the uploaded files are in a bucket, not in the data directory: back the bucket up with your provider's tools. See Media storage.

What to back up

FileWhat it is
workspace.dbThe SQLite database, the job queue included (scheduled posts and pending retries). Back it up with the backup command, never by copying the file.
uploads/Uploaded media, one folder per workspace (uploads/workspaces/<id>/). Their thumbs/ folders are a cache staqly rebuilds; you can skip them.
secret.keyDecrypts channel credentials and developer app secrets. Only there if you haven't set STAQLY_SECRET_KEY. Without it every channel has to be reconnected.
notify_secret.keyDecrypts alert secrets. Only there if you haven't set NOTIFY_SECRET_KEY.
access_tokenThe Community Edition's access token. Optional: without it a restored install makes a new token and your agents need the new one.

They are in ~/.local/share/staqly with the binary (or your --data directory), and in the staqly-data volume at /data with the Docker image.

Never copy workspace.db from a running server

Under WAL the latest commits may live only in workspace.db-wal, and a file copy taken mid-write can be torn. Use the backup command below.

Back up

Settings → Backups in the dashboard shows the backup commands for your install (binary or Docker), ready to copy. On Staqly Cloud it lists the workspace's backups instead.

staqly serve backup copies the database only, so archive the uploads next to it.

Back up the database

umask 077
mkdir -p ~/staqly-backups/2026-10-13
staqly serve backup ~/staqly-backups/2026-10-13/workspace.db

This works while staqly serve is running. Add --data (e.g. staqly serve --data ~/staqly-data backup ~/staqly-backups/2026-10-13/workspace.db) if you don't use the default data directory.

Archive uploads and the keys

cd ~/.local/share/staqly
tar czf ~/staqly-backups/2026-10-13/uploads.tar.gz --exclude='uploads/workspaces/*/thumbs' \
  uploads $(ls secret.key notify_secret.key access_token 2>/dev/null)

Take the database first and the uploads second (see Why the order matters).

Store it off the machine

Copy the backup folder somewhere else, encrypted.

Restore

Restoring replaces all current data with the backup.

Stop staqly

Press Ctrl-C. If it runs in the background, staqly service uninstall stops it (your data is kept); run staqly service install again afterwards.

Put the backup in place

cd ~/.local/share/staqly
rm -f workspace.db workspace.db-wal workspace.db-shm
cp ~/staqly-backups/2026-10-13/workspace.db workspace.db
rm -rf uploads
tar xzf ~/staqly-backups/2026-10-13/uploads.tar.gz
chmod 600 workspace.db

Delete the -wal and -shm files: stale WAL files must not be replayed onto the restored database.

Start staqly again

staqly serve

Pending migrations run automatically on start.

Sessions and API keys come back as they were at backup time. The access token is the access_token file: restored with it, agents keep working; otherwise the install keeps the token it has (or makes a new one).

Schedule backups

Run the backup from cron (or a systemd timer), then ship the backups off the machine.

Save the two backup steps as a script:

~/.local/bin/staqly-backup
#!/bin/sh
set -eu
umask 077
out="$HOME/staqly-backups/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$out"
"$HOME/.local/bin/staqly" serve backup "$out/workspace.db"
cd "$HOME/.local/share/staqly"
tar czf "$out/uploads.tar.gz" --exclude='uploads/workspaces/*/thumbs' uploads $(ls secret.key notify_secret.key access_token 2>/dev/null)

Make it executable (chmod +x ~/.local/bin/staqly-backup) and run it every night at 3:00:

crontab -e
0 3 * * *  $HOME/.local/bin/staqly-backup >> $HOME/staqly-backups/backup.log 2>&1

How backups work

A consistent snapshot

The backup command (staqly serve backup or server backup in the container) runs SQLite's VACUUM INTO: a transactionally consistent, compacted copy taken while the server keeps serving requests. The search index is rebuilt in the copy.

Why the order matters

Media files are written before the database row that references them and are never modified afterwards. Taking the database snapshot first and the uploads second therefore never yields a row pointing at a missing file.

Backups contain secrets

The database holds webhook signing secrets (in plain text — they are needed to sign), hashed API keys and sessions, sealed channel credentials and encrypted alert secrets; secret.key and notify_secret.key decrypt them. Run the backup commands with umask 077 as above, so only you can read the copies, and keep it that way: store backups encrypted, and don't commit them or put them on shared drives.

Staqly Cloud workspaces

On Staqly Cloud, workspace admins on a paid plan get backups in Settings → Backups: Create backup builds a ZIP of the whole workspace (collections, posts, channels without credentials, schedules, events and media), and each ready backup has a Download button for 24 hours. These are the workspace exports from Data export & privacy (POST /v1/workspace/export, GET /v1/workspace/exports). On the Starter plan the tab points to the data-only export in Settings → Data & privacy (no media files) instead. These downloads are your own copy of the workspace.

From a checkout (Compose)

If you develop staqly from the repository with Docker Compose, make backup (scripts/backup.sh) runs the Docker steps above against the Compose volume staqly_staqly-data and writes backups/<timestamp>/workspace.db and uploads.tar.gz (uploads without the thumbs cache, plus secret.key, notify_secret.key and access_token if present), all owner-only. make restore BACKUP=backups/<timestamp> (scripts/restore.sh) restores one; it asks for confirmation (FORCE=1 skips it). STAQLY_CONTAINER and STAQLY_VOLUME select another container or volume.

Next steps

On this page