Operations

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.