Welcome!
I struggled with Beets setup and wanted to share my configs, tips, and troubleshooting for anyone else working on music management with Docker and Portainer. These examples reflect how I tag music alongside Lidarr while keeping Lidarr responsible for the final library paths and filenames.
- Debian 12
- Docker
- Docker Compose (optional, for Portainer stacks)
- Portainer Business Edition (optional; note that stuck containers and stacks can occasionally require manual cleanup)
Host paths, user IDs, group IDs, and network names in docker-compose.yml are
specific to my installation. Change them before deploying the stack.
The root config.yaml is the complete standalone setup. It catalogs and tags
music in place and includes:
- MusicBrainz and Deezer metadata candidates
- AcoustID fingerprinting
- MusicBrainz and Last.fm genres, preserving up to seven useful genres
- Cover-art fetching and embedding
- Synced lyrics where available
- ReplayGain analysis with FFmpeg
- Tag cleanup, album-type tags, smart playlists, and the Beets web interface
The main profile does not move, copy, or rename music. Its path templates show
the equivalent Lidarr naming layout and become active only if import.move or
import.copy is deliberately enabled.
This maintenance profile improves metadata already inside a Lidarr-managed library. It writes tags in place while leaving all paths and filenames under Lidarr's control. Read its own README before running it against a library.
This maintenance profile catalogs an existing library without retagging it, then recalculates only track and album ReplayGain metadata when explicitly requested. It defaults to a -14 LUFS target for players without preamp controls and documents how to switch back to the standard -18 LUFS target.
This is an example Beets conversion profile for producing FLAC files from M4A sources in a separate destination. Converting lossy AAC to FLAC does not restore lost quality. The included sidecar script separately handles the uncommon case where an M4A container already holds a FLAC stream.
This directory preserves the Beets configs and helper files used by my Lidarr arr-scripts installation. They are kept as a reference and backup rather than as the main standalone Beets configuration.
-
Review and adjust every host path,
PUID,PGID, timezone, and network indocker-compose.yml. -
Place
config.yamlanddocker-compose-post-commands.shin the host folder mounted at/config. -
Make the startup script executable:
chmod +x docker-compose-post-commands.sh
-
Start the stack:
docker compose up -d
The startup script installs the optional Python dependencies required by the
enabled plugins, then launches the configured Beets web service on port 8337.
It no longer downloads the abandoned beets-popularity plugin.
Check that Beets can load the configuration and every enabled plugin:
docker exec -it -u abc beets beet -c /config/config.yaml version
docker exec -it -u abc beets beet -c /config/config.yaml configBack up the library, then test with a small album before importing a full music collection:
docker exec -it -u abc beets beet -c /config/config.yaml import /music/path-to-test-albumThe importer writes metadata, artwork, lyrics, and ReplayGain tags. It can still make incorrect metadata choices, so review uncertain matches instead of treating any automatic tagger as risk-free.
- Most configs and example files are well-commented; please read through them first.
- I use Lidarr arr-scripts to manage my music library.
- Lidarr handles final naming and organization while Beets focuses on metadata.
- I test new settings against a small folder before using them on the library.
- Spotify as the only indexer: After running for a while, only Spotify appeared as an indexer even with DNS access to MusicBrainz. The current main profile uses MusicBrainz as its primary source and does not require Spotify. Spotify can be enabled separately after adding valid application credentials.
- Multi-indexer genre combining: WLG was broken and its old integration was unreliable. The current profiles seed genres from MusicBrainz, preserve those values, and add the strongest Last.fm track genres up to a total of seven.
- Exporting lyrics (
.lrc): The current lyrics profile prefers synced data from LRCLIB and lrcmux and stores it in supported audio tags. Sidecar.lrcoutput remains player- and workflow-dependent. - Popularity playlists: The old
beets-popularityrepository is no longer available, so that plugin and its popularity queries were removed. Modern Beets can retrieve Spotify popularity withspotifysyncwhen the Spotify plugin and valid API credentials are configured.
Older snapshots may still contain (redacted) where private API credentials
were removed. Supply your own credentials when enabling those optional sources.
- Read through all config files and their comments before using them.
- Use Docker Compose for easier stack management, but be aware of Portainer quirks.
- Always back up your music library before testing new configs.
- Run
beet versionafter changing plugins so missing dependencies are caught before an import. - Keep Beets path management disabled when Lidarr owns the library structure.
- Discord: Join for help or discussion
- Issues: Feel free to open an issue with questions or suggestions.
Happy tagging and organizing!