Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration

tapedeck reads one TOML file: --config PATH, $TAPEDECK_CONFIG, or $XDG_CONFIG_HOME/tapedeck/config.toml (~/.config/tapedeck/config.toml). Unknown keys are an error, so typos fail at startup.

A complete example lives in config.example.toml.

Top level

KeyDefaultMeaning
libraryrequiredRoot of the music library. Downloads land under it.
path_template{album_artist}/{album} ({year})/{track:02} - {title}.{ext}Where a track is filed, relative to library. See below.
themecatppuccin-mochaTUI colours. A built-in name (catppuccin-mocha, catppuccin-latte) or the stem of a file in themes/ next to config.toml. See Themes.
playlist_dir<library>/playlistsWhere the m3u8 files go: one current file per playlist kind (weekly-jams.m3u8), superseded ones under archive/<kind>/, playlist backups under backup/<target>/. Lowercase slugs throughout.
database$XDG_DATA_HOME/tapedeck/tapedeck.dbSQLite file.
socket$XDG_RUNTIME_DIR/tapedeck.sockDaemon socket. Falls back next to the database if XDG_RUNTIME_DIR is unset.

Path template

Lidarr-style tokens inside {}:

TokenValue
{artist}Track artist credit as MusicBrainz prints it (A feat. B).
{album_artist}Artist credit of the release the track was filed under. Differs from {artist} on compilations and guest features.
{album}Release title.
{year}Release year, or Unknown.
{track} / {track:02}Track number, plain or zero-padded.
{title}Recording title.
{ext}File extension from the download.

Every token value is sanitized: / \ : * ? " < > | and control characters become _, so a title can never create a directory. Literal text outside braces is kept as is, including slashes, which is how you shape the directory tree. An unknown token is a startup error.

[listenbrainz]

KeyDefaultMeaning
userrequiredListenBrainz username whose created-for playlists to follow.
tokennoneUser token. Only needed if the playlists are private.
token_filenonePath to a file containing the token, instead of token. See Secrets.
playlists["weekly-jams", "weekly-exploration"]Which generated playlists to track, by ListenBrainz source_patch name. daily-jams is the other common one.

[download]

KeyDefaultMeaning
backendytdlpDownload backend. Only ytdlp exists today.
formatopusPassed to yt-dlp --audio-format.
ytdlp_binyt-dlpExecutable name or path.
ffmpeg_binnonePassed to yt-dlp as --ffmpeg-location. Default: whatever yt-dlp finds on PATH.

yt-dlp is searched with ytsearch1:<artist> - <title> unless a track has an explicit source_url in the database. ffmpeg must be available for the audio extraction.

[sync]

KeyDefaultMeaning
interval6hHow often the daemon runs sync. Suffixes: s, m, h, d.
on_starttrueSync as soon as the daemon starts, and after every restart (which includes a Plex push). false waits one interval first.
targets[]Enabled targets, in push order. Only plex exists today.
playlist_title{name}Playlist name on the targets. {name} is the kind in title case (Weekly Jams), {kind} the raw kind (weekly-jams). Use something like {name} (tapedeck) if another tool already owns the plain names.

[sync.plex]

KeyMeaning
urlServer URL, e.g. http://plex.local:32400.
tokenX-Plex-Token. Find it via Plex’s “Get Info → View XML” on any item.
token_filePath to a file containing the token, instead of token. One of the two is required.
sectionName of the music library section, usually Music.
path_mapLocal prefix → the prefix Plex sees, e.g. { "/srv/music" = "/music" } for a container. Longest match wins. Leave out if identical.

[lyrics]

Lyrics from LRCLIB; see Lyrics. enable (default true), write_sidecars (default true, .lrc/.txt next to own tracks), external ("db-only", the default, or "missing-sidecars" to also write next to external files that have none), retry_after (default 30d) and interval (default 6h, "0" off).

[steam]

Game soundtracks bought on Steam, imported as they are; see Steam soundtracks. path is the Steam client’s steamapps/music; username a steamcmd account (logged in once by hand) whose owned soundtracks are downloaded. Either or both. steamcmd_bin (default steamcmd), staging (default steam/ next to the database) and interval (default 24h, "0" off) tune the download side.

[steam]
path = "/home/you/.local/share/Steam/steamapps/music"
username = "you"

[server.subsonic]

Sign-in for Subsonic clients on /rest/, served on the [server] listen port. Without user, every Subsonic client is anonymous and gets the anonymous scopes (enough on a LAN). With user and password or password_file, clients must sign in and then may do everything.

[server.subsonic]
user = "mirza"
password_file = "/run/secrets/subsonic-password"

Environment variables

Every key can also come from the environment, which is how a container gets its paths and secrets without a mounted file. The name is TAPEDECK_ followed by the key path with __ (two underscores) between levels, in any case:

TAPEDECK_LIBRARY=/music
TAPEDECK_LISTENBRAINZ__USER=you
TAPEDECK_LISTENBRAINZ__PLAYLISTS='["weekly-jams", "daily-jams"]'
TAPEDECK_SYNC__TARGETS='["plex"]'
TAPEDECK_SYNC__PLEX__URL=http://plex:32400
TAPEDECK_SYNC__PLEX__SECTION=Music
TAPEDECK_SYNC__PLEX__TOKEN_FILE=/run/secrets/plex-token
TAPEDECK_SERVER__LISTEN=0.0.0.0:8687

Environment wins over the file. true/false and values starting with [, { or " are read as TOML (arrays, inline tables, quoted strings); everything else is taken as a string, so paths, URLs and durations need no quotes. An empty value removes the key, which switches off a default the container image sets (TAPEDECK_SERVER__LISTEN=). When at least one TAPEDECK_* variable is set, the config file may be missing altogether; TAPEDECK_CONFIG itself names the file and is not a key.

Secrets work the same way: TAPEDECK_LISTENBRAINZ__TOKEN=… or, better, a TOKEN_FILE pointing at a mounted secret, so the token never shows up in docker inspect.

Secrets

Every token has a token_file twin. tapedeck reads the file when it is about to talk to that service (the daemon at start, an in-process command when it needs the target; never for commands that go through a running daemon’s socket), strips the trailing newline, and from then on behaves as if token had been set. Setting both is an error. This is how you keep tokens out of a config that lives in Git or in the Nix store: point token_file at whatever sops-nix, agenix or systemd-creds puts on disk.

The sections for [player], [server]/[remote], [telegram] and [external] are on their own pages: The TUI, Remote use, Song requests and External libraries. The NixOS and Home Manager modules are under Installation.