Skip to content

Backup and restore

What to back up in a Shellius deployment, how to do it, and how to prove a restore actually works.

What has to be backed up ​

Three things, and they are not equally replaceable.

WhatWhereIf you lose it
SERVER_ENCRYPTION_KEY.env.prodThe CA private key is unrecoverable, even with a perfect database backup. Every host must be re-bootstrapped.
The databasePostgres volumeYou lose servers, policies, users, requests, and the audit log.
Session recordings/data/recordings in the API containerYou lose replay history. Often subject to a retention requirement.

DANGER

A database backup without SERVER_ENCRYPTION_KEY is close to worthless — the CA private key and stored credentials in it are encrypted with that key. Back the key up separately, somewhere that is not the server it runs on, and confirm you can actually read it.

Backing up ​

The repository ships two scripts. Both write to ./backups/ and keep 14 days.

bash
./scripts/backup-db.sh            # pg_dump, gzipped
./scripts/backup-recordings.sh    # tars the recordings volume

They take the compose project name as an argument if yours is not shellius.

A reasonable cron:

txt
15 2 * * *  cd /opt/shellius && ./scripts/backup-db.sh >> /var/log/shellius-backup.log 2>&1
45 2 * * 0  cd /opt/shellius && ./scripts/backup-recordings.sh >> /var/log/shellius-backup.log 2>&1

./backups/ lives next to your .env.prod, so it is on the same machine as the thing it is protecting. Ship it somewhere else — object storage, another host, anything — or it will not survive the failure you are backing up for.

Restoring the database ​

Stop the API first so nothing writes while you restore:

bash
docker compose -f docker-compose.prod.yml stop backend

gunzip -c backups/db-2026-09-20_02-15-00.sql.gz \
  | docker exec -i shellius-postgres-1 psql -U shellius -d shellius

docker compose -f docker-compose.prod.yml start backend

Restoring into a database that already has data will conflict. Restore into an empty database — either a fresh volume or a dropped and recreated one. Be certain which you are pointing at.

Restoring recordings ​

bash
gunzip -c backups/recordings-2026-09-20_02-45-00.tar.gz \
  | docker exec -i shellius-backend-1 tar -C /data -xf -

Prove the restore works ​

A backup you have never restored is a hypothesis. Once a quarter:

  1. Restore the latest dump into a scratch deployment with a copy of the real SERVER_ENCRYPTION_KEY.
  2. Sign in.
  3. Confirm the certificate authority public key matches production. This is the real test — it proves the key decrypts the CA.
  4. Confirm servers, policies, and audit history are present.

If step 3 fails, your key backup is wrong, and you would only have found out during an outage.

What is not in a backup ​

Certificates are short-lived and are not worth restoring; they will be reissued. Host-side state (/etc/ssh/shellius_ca.pub, the agent token) is not backed up by Shellius either — it is reproduced by re-bootstrapping the host.

Was this page helpful?No, tell us why