Backup and restore
Everything SchellingBoard stores lives in one Docker volume, mounted at
/data: the database (/data/data.db) and any files uploaded through the
admin UI, such as guest avatars and the venue map (/data/uploads).
.env separatelyIt is not in that volume, and it holds AUTH_SECRET, SITE_PASSWORD,
ADMIN_PASSWORD and your SMTP credentials. Restoring the data without the
same AUTH_SECRET logs everyone out.
Find the volume
The examples below use $VOL for the volume name. With docker compose it is
your project directory plus _data; with the plain docker run command from
Deployment it is schellingboard_data.
docker volume ls | grep data
VOL=schellingboard_data
Back up without stopping the site
cp or tar a live data.dbA write in progress leaves you with a truncated file that looks fine until you try to restore it.
Use SQLite’s own backup command instead, which takes a consistent snapshot of a database that is being written to:
mkdir -p ./backups
STAMP=$(date +%Y%m%d-%H%M%S)
docker run --rm \
-v "$VOL:/data" \
-v "$PWD/backups:/backup" \
alpine sh -c "apk add --no-cache sqlite >/dev/null && \
sqlite3 /data/data.db \".backup '/backup/data-$STAMP.db'\" && \
tar czf /backup/uploads-$STAMP.tar.gz -C /data uploads"
This leaves backups/data-<stamp>.db and backups/uploads-<stamp>.tar.gz on
the host. It runs against the live volume, so no downtime and no dropped
requests.
Run it from cron to get regular backups, and copy the results somewhere off
the machine — a backup that only exists on the server it came from does not
survive losing the server.
Back up with the site stopped
If a few seconds of downtime is fine, stopping the app first means a plain archive of the whole volume is safe, and there is nothing to keep in sync:
docker compose stop app
docker run --rm -v "$VOL:/data:ro" -v "$PWD/backups:/backup" \
alpine tar czf "/backup/volume-$STAMP.tar.gz" -C /data .
docker compose start app
Restore
Stop the app, put the files back, and start it again:
docker compose stop app
docker run --rm -v "$VOL:/data" -v "$PWD/backups:/backup" alpine sh -c "
rm -rf /data/data.db /data/data.db-wal /data/data.db-shm /data/uploads &&
cp /backup/data-$STAMP.db /data/data.db &&
tar xzf /backup/uploads-$STAMP.tar.gz -C /data &&
chown -R 1001:1001 /data"
docker compose start app
- The
chownmatters. SchellingBoard runs as user1001inside the container but the helper above writes asroot, so without it the app cannot open its own database. - Restoring into a newer version works — it migrates the database on
startup. Restoring into an older one does not, so pin
SCHELLINGBOARD_VERSIONto the version the backup came from if you are rolling back. - Check afterwards by opening the site: events, proposals and sessions should be there, and the venue map and guest avatars should load.