Deploying Beets
Beets is a lightweight, open-source music library manager and metadata tagger that helps you organize, curate, and enjoy your music collection. Designed for music enthusiasts and professionals alike, Beets automates the tedious process of organizing music files, fetching metadata from multiple sources, and managing your entire music library with precision and ease. Whether you have hundreds or hundreds of thousands of songs, Beets provides powerful tools to keep your music organized and metadata accurate.
Why Beets?
Beets stands out in the music management landscape with its powerful features and flexibility:
- Automatic Tagging: Intelligently matches songs to online metadata databases, automatically filling in artist, album, track information with minimal errors
- Metadata Sources: Integrates with multiple metadata providers including MusicBrainz, Discogs, and Spotify for comprehensive and accurate information
- Flexible Organization: Organize music files by artist, album, year, genre, or custom naming schemes
- Audio Quality Detection: Identifies and manages bitrate, format, and audio quality of your files
- Plugin Ecosystem: Extend functionality with official and community plugins for additional features
- Web Interface: Optional web-based interface for browsing and managing your library remotely
- Import Management: Smart duplicate detection and handling during library imports
- Format Conversion: Optional audio transcoding and format conversion capabilities
- Batch Operations: Efficiently manage and organize large music collections
- Command-Line Interface: Powerful CLI for scripting and automation
- Cross-Platform: Works on Linux, macOS, Windows, and Docker containers
- Open Source: MIT licensed with active community development and support
Beets is perfect for music lovers, audio professionals, and anyone who wants complete control over their music library organization. With persistent storage on Klutch.sh, your music collection and metadata are always safe, searchable, and accessible.
Prerequisites
Before deploying Beets, ensure you have:
- A Klutch.sh account
- A GitHub repository with your Beets deployment configuration
- Basic familiarity with Docker and Git
- (Optional) A music library to organize (can be empty initially)
Deploying Beets
Create a New Project
Log in to your Klutch.sh dashboard and create a new project for your Beets deployment.
Prepare Your Repository
Create a GitHub repository with the following structure for your Beets deployment:
beets-deploy/├─ Dockerfile├─ config.yaml├─ .gitignore└─ README.mdHere’s a production-ready Dockerfile for Beets:
FROM python:3.11-slimWORKDIR /app# Install system dependenciesRUN apt-get update && apt-get install -y \git \curl \ffmpeg \imagemagick \&& rm -rf /var/lib/apt/lists/*# Install Beets and common pluginsRUN pip install --no-cache-dir \beets \beautifulsoup4 \flask \requests# Create necessary directoriesRUN mkdir -p /music /app/config /app/logs# Expose port 8337 for web interfaceEXPOSE 8337# Set working directory for BeetsWORKDIR /music# Copy configurationCOPY config.yaml /app/config/config.yaml# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \CMD curl -f http://localhost:8337 || exit 1# Start Beets with web interfaceCMD ["beet", "web", "-l", "0.0.0.0", "-p", "8337"]Create a
config.yamlfile for Beets configuration:directory: /music/librarylibrary: /app/config/library.dbimport:autotag: yeswrite: yescopy: yestimid: nolog: /app/logs/import.logplugins:- web- thumbnails- mbsync- lyricsweb:host: 0.0.0.0port: 8337musicbrainz:enabled: yesimport:resume: askCommit and push to your GitHub repository:
Terminal window git initgit add .git commit -m "Initial Beets deployment"git remote add origin https://github.com/yourusername/beets-deploy.gitgit push -u origin mainCreate a New App
In the Klutch.sh dashboard:
- Click “Create New App”
- Select your GitHub repository containing the Dockerfile
- Choose the branch (typically
mainormaster) - Klutch.sh will automatically detect the Dockerfile in the root directory
Configure Environment Variables
Set up these environment variables in your Klutch.sh dashboard:
Variable Description Example PYTHONUNBUFFEREDPython output buffering 1BEETSDIRBeets configuration directory /app/configMUSICBRAINZ_RATE_LIMITMusicBrainz API rate limit (requests per second) 1ACOUSTIDAPI_KEYAcoustID API key (optional for audio fingerprinting) your-api-keyDISCOGS_TOKENDiscogs API token (optional for Discogs metadata) your-tokenConfigure Persistent Storage
Beets requires persistent storage for your music library and metadata database. Add persistent volumes:
Mount Path Description Recommended Size /music/libraryYour music collection 500GB+ (adjust based on library size) /app/configBeets configuration and database 10GB In the Klutch.sh dashboard:
- Navigate to your app settings
- Go to the “Volumes” section
- Click “Add Volume” for each mount path
- Set mount paths and sizes as specified above
Set Network Configuration
Configure your app’s network settings:
- Select traffic type: HTTP
- Internal port: 8337 (the Beets web interface port)
- Klutch.sh will automatically handle HTTPS termination
Deploy Your App
- Review all settings
- Click “Deploy”
- Klutch.sh will build the Docker image and start your Beets instance
- Wait for the deployment to complete (typically 3-5 minutes)
Initial Setup and Configuration
After deployment completes, access your Beets instance:
Accessing the Web Interface
Navigate to your app’s URL: https://example-app.klutch.sh
You’ll see the Beets web interface showing your music library. Initially, it will be empty until you import music.
Importing Your Music Library
The primary way to add music to Beets is through the import process:
-
Prepare Your Music
- Place your music files in an easily accessible location
- Supported formats: MP3, FLAC, OGG, M4A, WMA, and more
-
Import from Web Interface (if enabled)
- Use the web interface to browse and import music
- Beets will automatically fetch metadata and organize files
-
Import via Command Line (advanced)
- SSH into your Beets instance and run:
Terminal window beet import /path/to/music
- SSH into your Beets instance and run:
Configuration Best Practices
In your config.yaml:
directory: /music/library # Main music library directorylibrary: /app/config/library.db # Database locationimport: autotag: yes # Automatically tag imports write: yes # Write metadata to files copy: yes # Copy files to library directory timid: no # Require user confirmation for changes log: /app/logs/import.log # Log import operations
plugins: - web # Web interface - thumbnails # Album artwork - mbsync # Keep metadata in sync - lyrics # Fetch lyrics
web: host: 0.0.0.0 # Listen on all interfaces port: 8337 # Web interface port
musicbrainz: enabled: yes # Use MusicBrainz for taggingEnvironment Variables and Configuration
Basic Beets Configuration
PYTHONUNBUFFERED=1BEETSDIR=/app/configMUSICBRAINZ_RATE_LIMIT=1Advanced Configuration
For fine-tuned control over Beets behavior:
BEETS_AUTO_UPDATE_CACHE=trueBEETS_IMPORT_RESUME=askBEETS_IMPORT_QUIET=falseBEETS_IMPORT_VERBOSE=falseBEETS_LIBRARY_SIZE_LIMIT=1000000BEETS_LOG_LEVEL=infoPlugin Configuration
Enable and configure optional plugins:
# Enable album art downloadingENABLE_THUMBNAILS=true
# Enable lyrics fetchingENABLE_LYRICS=true
# Enable MusicBrainz syncENABLE_MBSYNC=true
# Discogs pluginENABLE_DISCOGS=trueDISCOGS_TOKEN=your-discogs-tokenSample Code and Getting Started
Using the Beets Web Interface
Once deployed and music is imported, you can:
-
Browse Your Library
- View albums, artists, and genres
- Search for specific songs or albums
- Filter by various criteria
-
View Metadata
- See all tag information for songs
- View album artwork and metadata
- Check import status and logs
Command-Line Examples (if SSH access available)
# List all albums in librarybeet list -a
# List all songs by an artistbeet list artist:Radiohead
# Search for songs with missing metadatabeet list -f '$artist - $title' mb:none
# Update library statisticsbeet stats
# Modify metadata for a songbeet modify artist:Radiohead title:Creep artist="Radiohead"Importing Music Programmatically
# Import a directory with automatic taggingbeet import -s /music/incoming
# Import with manual confirmation for each albumbeet import /music/incoming
# Import and overwrite existing filesbeet import -W /music/incoming
# Import from remote locationbeet import /mnt/external-drive/musicAPI Examples (Web Interface)
# Get library statistics (if API available)curl https://example-app.klutch.sh/api/stats
# Search the library (if API available)curl "https://example-app.klutch.sh/api/search?q=radiohead"
# Get album information (if API available)curl "https://example-app.klutch.sh/api/albums/1"Docker Compose for Local Development
For local testing before deploying to Klutch.sh:
version: '3.8'
services: beets: image: python:3.11-slim working_dir: /music volumes: - ./music:/music/library - ./config:/app/config - ./logs:/app/logs ports: - "8337:8337" environment: - PYTHONUNBUFFERED=1 - BEETSDIR=/app/config - MUSICBRAINZ_RATE_LIMIT=1 command: > bash -c "pip install beets beautifulsoup4 flask requests && beet web -l 0.0.0.0 -p 8337" restart: unless-stoppedSave as docker-compose.yml and run:
docker-compose up -dAccess Beets web interface at http://localhost:8337
Music Library Organization
Directory Structure
Beets organizes music with customizable naming schemes. Default structure:
/music/library/├── Artist Name/│ ├── Album Name/│ │ ├── 01 - Song Title.mp3│ │ ├── 02 - Song Title.mp3│ │ └── cover.jpg│ └── Another Album/│ └── ...└── Another Artist/ └── ...Custom Organization
Customize the organization pattern in config.yaml:
paths: default: $albumartist/$album%aunique/$track $title singleton: Non-Album/$artist/$title comp: Compilations/$album%aunique/$track $titleBacking Up Your Music Library and Database
Persistent Volume Backups
Regular backups are essential for your music collection:
-
Via Klutch.sh Volume Snapshots
- Use your cloud provider’s volume snapshot feature
- Schedule regular snapshots of both
/music/libraryand/app/configvolumes
-
Manual Database Backup
- Export the Beets database regularly
- Backup the configuration files
Backup Procedures
# Backup Beets databasesqlite3 /app/config/library.db ".backup /app/config/library-backup.db"
# Create a tarball of configurationtar -czf beets-config-backup.tar.gz /app/config/
# Create a tarball of music library (large operation)tar -czf music-library-backup.tar.gz /music/library/Database Setup and Migration
Beets Database
Beets uses SQLite by default for storing metadata. The database is stored at:
/app/config/library.dbBacking Up and Restoring
# Backup the databasesqlite3 /app/config/library.db ".backup /backup/library.db"
# Restore from backupsqlite3 /app/config/library.db ".restore /backup/library.db"
# Export database to SQLsqlite3 /app/config/library.db ".dump" > library-export.sqlScaling and Performance
Vertical Scaling
For larger music libraries (100,000+ songs):
- Navigate to your app settings in Klutch.sh
- Increase instance resources:
- Minimum 2 CPU cores
- Minimum 2GB RAM
- Increase volume sizes to accommodate library growth
Performance Optimization
For large libraries, optimize configuration:
import: auto_update_cache: yes resume: ask duplicate_resolution: skip
musicbrainz: rate_limit_interval: 1.0 # Slow down API requests to avoid timeoutsDatabase Optimization
# Rebuild the database indexbeet library-rebuild
# Clear the MusicBrainz cachebeet mb-resetCustom Domain Configuration
To use your own domain with Beets:
- Navigate to your app’s “Domains” section in Klutch.sh
- Click “Add Custom Domain”
- Enter your domain (e.g.,
music.yourdomain.com) - Configure your DNS provider with a CNAME record:
music.yourdomain.com → example-app.klutch.sh
- Klutch.sh automatically provisions SSL certificates
Advanced Plugins and Extensions
Installing Additional Plugins
Add plugins to your requirements.txt:
beetsbeets-yearfolderbeets-alternativesbeets-copyartifactsbeets-inlineUpdate your Dockerfile to install from requirements:
COPY requirements.txt /app/RUN pip install --no-cache-dir -r /app/requirements.txtPopular Plugins
- yearfolder: Organize albums by year
- alternatives: Maintain multiple copies of files in different formats
- copyartifacts: Copy non-music files (artwork, lyrics) with imports
- inline: Dynamically modify metadata during import
- replaygain: Calculate ReplayGain tags
- acousticbrainz: Download AcoustBrainz tags for audio analysis
Security Best Practices
Authentication and Access Control
- Restrict access to your Beets instance with a reverse proxy if needed
- Use strong passwords if authentication is enabled
- Keep API keys secure in environment variables
- Never commit sensitive information to your repository
Network Security
- Always use HTTPS (Klutch.sh provides this automatically)
- Limit API access if exposing to the internet
- Monitor access logs for unauthorized activity
- Keep Beets and dependencies updated
Data Privacy
- Your music collection stays on your server
- No automatic phone-home or telemetry
- Full control over metadata sources used
- Regular backups ensure data resilience
Troubleshooting
Common Issues and Solutions
Issue: Web interface not accessible
Check that:
- Port 8337 is correctly configured
- Container is running (check logs in Klutch.sh dashboard)
- Network configuration is set to HTTP traffic type
Issue: Music files not appearing in library
Solutions:
- Ensure music files are in
/music/librarydirectory - Verify file formats are supported (MP3, FLAC, OGG, M4A)
- Check import logs:
cat /app/logs/import.log - Run manual import:
beet import /music/incoming
Issue: Slow metadata fetching
Causes and solutions:
- Adjust
MUSICBRAINZ_RATE_LIMITto slow down API requests - Increase instance resources
- Clear MusicBrainz cache:
beet mb-reset - Check network connectivity
Issue: Database corruption
Recovery steps:
- Restore from backup:
sqlite3 /app/config/library.db ".restore /backup/library.db" - Rebuild database:
beet library-rebuild - Reimport music if necessary
Issue: Disk space issues
Solutions:
- Check volume usage in Klutch.sh dashboard
- Increase persistent volume size
- Remove old import logs:
rm /app/logs/*.log - Archive old media if needed
Upgrading Beets
To update Beets to a newer version:
- Update your Dockerfile:
RUN pip install --no-cache-dir --upgrade beets
- Commit and push to GitHub
- Klutch.sh will automatically rebuild with the latest version
- Test the updated version thoroughly
Advanced Configuration
Custom Metadata Processing
import: autotag: yes write: yes move: yes
match: strong_rec_thresh: 0.10 medium_rec_thresh: 0.25 weak_rec_thresh: 0.50 max_rec: 0.95Integration with Other Services
Export music metadata to other systems:
plugins: - web - export
export: json: yes csv: yesCustom Import Behavior
import: resume: ask incremental: yes incremental_skip_later: yes from_scratch: noAdditional Resources
- Beets Official Website - Documentation and guides
- Beets Configuration Reference - Complete config options
- Beets GitHub Repository - Source code and issue tracking
- MusicBrainz - Metadata database
- AcoustID - Audio fingerprinting service
- Klutch.sh Getting Started Guide
- Klutch.sh Volumes Documentation
- Klutch.sh Custom Domains Guide
Conclusion
Deploying Beets on Klutch.sh provides you with a powerful, self-hosted music library management system that keeps your entire music collection organized, searchable, and properly tagged. With persistent storage for your music files and metadata, advanced tagging capabilities, and an intuitive web interface, Beets transforms the way you manage and enjoy your music. Klutch.sh’s managed infrastructure ensures your music library is always available, secure, and performant.
Start organizing your music collection today by deploying Beets on Klutch.sh and experience the benefits of a properly curated music library.