Backups, restores and upgrades
Everything Outbound OS stores is in one Docker volume, outboundos-data: the SQLite database and instance-secrets.json. Back up both, keep a copy off the server, and an upgrade or a move to a new machine is routine.
instance-secrets.json together. Saved WhatsApp, email and iMessage credentials are encrypted with a key in that file; a database restored without it loses every saved credential.Back up
The included script takes a consistent copy while the app is running, checks its integrity, compresses it and keeps the newest seven:
docker compose exec app bash scripts/backup.sh
docker compose cp app:/app/data/backups ./backups
docker compose cp app:/app/data/instance-secrets.json ./backups/Then copy ./backups somewhere that is not this server — object storage, another machine, an encrypted drive. Treat it as sensitive: it holds your contacts and the key to your credentials.
Every night
Add a cron entry on the host, adjusting the path:
0 2 * * * cd /opt/outbound-os && docker compose exec -T app bash scripts/backup.shRestore, or move to a new server
- On the new server, install as usual with the same
.envand start it once so the volume exists. - Put the backup and
instance-secrets.jsonin abackupsfolder next todocker-compose.yml. - Stop the app, copy both files into the volume, and start again:
docker compose stop app
docker compose run --rm --no-deps -v "$PWD/backups:/restore:ro" app sh -c \
'gunzip -c /restore/outbound-os_20260928_020000.db.gz > /app/data/outboundos.db \
&& cp /restore/instance-secrets.json /app/data/instance-secrets.json'
docker compose up -dUse your own backup’s file name. The one-off container runs as the same user as the app, so file ownership is right, and any migrations the backup is missing run on start.
Upgrade
- Read the changelog for anything that needs a new setting.
- Take a backup.
- Pull the new images and restart:
git pull
docker compose pull && docker compose up -dCompose runs the published images from GitHub Container Registry, for both Intel and ARM servers. Database migrations run automatically before the app starts. If you run the MCP server, add --profile mcp to both commands.
To stay on one version, set OUTBOUNDOS_VERSION=0.2.0 in .env. Running your own changes to the code? docker compose up -d --build builds from the folder instead.
Roll back
Set OUTBOUNDOS_VERSION back to the previous release, start it, and restore the backup you took before upgrading. Migrations only move forward, so a database that has already been migrated should not be run with older code.
OUTBOUNDOS_VERSION=0.2.0
docker compose pull && docker compose up -dVersions before 0.2.0 have no published image. To go back to one of those, check out its tag and build it: git checkout v0.1.0 && docker compose up -d --build.