Skip to content

Backups & DATA_DIR

DATA_DIR is everything Trobar keeps: the SQLite database (users, devices, selections, playlists, provider config), the cover/artist-image caches, the transcode cache, user avatars, the session secret key, and the Roon pairing token. Your music library is not in here — Trobar treats MUSIC_ROOT as read-only truth that you back up separately.

What to back up

Back up DATA_DIR. Because it holds plaintext provider credentials and the session key, treat it like a password store — back it up encrypted, and restrict who can read it.

The credential key. The Maloja API key, ListenBrainz user token and Last.fm session that send plays, the Last.fm shared secret, and each person's Tidal refresh token are encrypted with a key in credential_key. A database snapshot doesn't include that file, so a leaked snapshot doesn't give anyone those values, and a copy of all of DATA_DIR does include it. To keep it out, set TROBAR_CREDENTIAL_KEY_FILE to a path outside DATA_DIR and back that file up separately. If the key is lost or changes, nothing breaks: those values read as gone, their owners see a request to enter them again (for Tidal, Connect again on their Profile), and plays, playlists and every other setting stay as they were. A key file that is damaged is different:

  • the play-sending credentials read as gone, and saving one fails until you delete that file; Trobar makes a new key the next time one is saved;
  • Tidal links are kept. Tidal syncs for those people stop until the key works again, and linking Tidal is refused meanwhile. A token Tidal renews during a sync in that time is stored unencrypted, until a start with a working key encrypts it. Restore the key from a backup if you have one: deleting the damaged file makes it a lost key, and everyone connects Tidal again.

Back it up to the NAS — don't run it from there

A network share is a fine destination for these backups and a dangerous home for DATA_DIR itself. SQLite needs working file locking, which NFS, SMB/CIFS and similar shares don't provide reliably; running the live database from one can corrupt it.

So: keep DATA_DIR on local disk on the machine running the server, and copy the snapshots produced below onto your NAS. That gets you the durability you wanted without risking the database. See Installation.

How

While Trobar keeps running

The database runs in SQLite's WAL mode: recent writes sit in music-sync.db-wal until SQLite folds them into music-sync.db. So a plain copy or tar of a running DATA_DIR is not a safe backup. It can catch the two files at different moments, and a database restored from that can be missing writes or be corrupt.

Let SQLite take the copy instead. Its backup API produces a consistent snapshot while the server keeps reading and writing. The image has no sqlite3 command, so use its Python:

# 1. A consistent copy of the database, next to the live one.
docker compose exec trobar python -c "import sqlite3; dst = sqlite3.connect('/data/music-sync.db.snapshot'); sqlite3.connect('/data/music-sync.db').backup(dst); dst.close()"

# 2. Everything else, leaving out the live database files.
sudo tar czf trobar-data-$(date +%F).tar.gz -C ./data \
  --exclude=./music-sync.db --exclude=./music-sync.db-wal --exclude=./music-sync.db-shm .

# 3. Remove the snapshot from DATA_DIR again.
docker compose exec trobar rm /data/music-sync.db.snapshot

sudo, because the files belong to the container's uid 10001 and some (the session key) are readable by that user only. A plain tar stops at them.

The transcode cache, transcode/, can be left out with --exclude=./transcode: it holds only copies the server makes again as devices sync, up to the size set in Administration.

For a named volume, run step 2 in a throwaway container:

docker run --rm -v <volume>:/data -v "$PWD":/backup alpine \
  tar czf /backup/trobar-data-$(date +%F).tar.gz -C /data \
  --exclude=./music-sync.db --exclude=./music-sync.db-wal --exclude=./music-sync.db-shm .

The archive holds the database as music-sync.db.snapshot; Restore says what to do with it.

With the server stopped

Stopping the stack first also gives a consistent copy, with no snapshot step:

docker compose down
sudo tar czf trobar-data-$(date +%F).tar.gz -C ./data .   # bind-mount default
docker compose up -d

For a named volume:

docker run --rm -v <volume>:/data -v "$PWD":/backup alpine \
  tar czf /backup/trobar-data-$(date +%F).tar.gz -C /data .

Restore

Stop the stack, replace the contents of DATA_DIR with the backup, make sure everything is owned by uid 10001 (see Upgrading), and start again.

If the backup was taken while Trobar was running, rename music-sync.db.snapshot to music-sync.db. Make sure no music-sync.db-wal or music-sync.db-shm is left in DATA_DIR from before: SQLite would apply a leftover -wal to the restored database.

The caches rebuild themselves

Losing only the cover/artist-image caches is harmless — they re-fetch. The database is the part that matters; a device that still has its files can even re-seed the server after a database loss (the client uploads its manifest and the server re-matches it), but a proper backup is the intended safety net. See Device loss, replacement & migration for the per-client details of that recovery path, and for what happens when it's the device that's lost or replaced instead.