Storage and backups#
VTune keeps its SQLite database, converted Ogg Opus media, staged uploads, migration backups, and related state beneath DATA_DIR. Protect the complete persistent volume.
What persists#
- Account, library, group, sharing, settings, invitation, and audit metadata.
- Converted library audio under generated owner and track keys.
- Durable upload jobs and resumable staged bytes.
- Automatic pre-migration SQLite backups.
Voice sessions and playback queues intentionally remain in memory and reset on restart.
Built-in verified backup#
VTune can create a portable backup containing a consistent SQLite snapshot,
library media, and durable staged uploads. It writes a versioned manifest with
SHA-256 hashes, cross-checks stored file sizes against SQLite, and verifies the
finished result before reporting success. The destination must not already
exist and must be outside DATA_DIR.
Stop the service during capture so library and staged files cannot change around
the database snapshot. Mount an operator-controlled host directory at /backup;
ensure it is private and writable by container UID 1000.
install -d -m 700 backups
backup_id="vtune-$(date -u +%Y%m%dT%H%M%SZ)"
docker compose -f compose.release.yaml stop vtune
docker compose -f compose.release.yaml run --rm --no-deps \
--volume "$(pwd)/backups:/backup" vtune \
node dist/scripts/backup.js create --destination "/backup/$backup_id"
docker compose -f compose.release.yaml run --rm --no-deps \
--volume "$(pwd)/backups:/backup:ro" vtune \
node dist/scripts/backup.js verify --backup "/backup/$backup_id"
docker compose -f compose.release.yaml start vtune
curl --fail http://127.0.0.1:3000/readyz
Use --json for automation. Backups contain account data, media, session and
invitation hashes, and other private metadata. Protect them like production
data, copy them off-host, and apply an independent retention policy. The tool
excludes .env, transient chunks/conversion files, logs, and unrelated files.
Automatic migration backups do not replace this operator-controlled backup.
The creation command uses distinct exit statuses for invalid source data,
existing destinations, creation failures, and verification failures. Never
treat the presence of a backup directory alone as success; require the command
to exit successfully and retain its manifest.json.
Restore test#
At least once per release, run the verification command again, then restore the
backup into a new disposable data volume with a separate hostname and Discord
application. Restore database/vtune.db as <DATA_DIR>/vtune.db, media/ as
<DATA_DIR>/library/, and tmp/ as <DATA_DIR>/tmp/; keep ownership with the
unprivileged container user. Run doctor, start the disposable instance, and
confirm the database opens, library metadata matches stored media, resumable
uploads remain coherent, and a test track plays before calling the backup usable.
The built-in tool intentionally does not overwrite or restore a live data directory. Restore is an explicit operator action so a mistyped command cannot silently replace production state.