How to Self-Host Mopidy with Docker Compose
Unlike Most Music Servers, Mopidy Is a Backend
Mopidy doesn’t ship with a fancy web UI or mobile app. It’s a music server daemon that speaks the MPD (Music Player Daemon) protocol and exposes an HTTP API. You choose your own frontend — dozens of MPD clients, web UIs, and mobile apps work with it.
This modular design is Mopidy’s strength and its weakness. You get exactly the features you want through extensions, but you assemble the stack yourself. If you want a batteries-included experience, look at Navidrome. If you want a customizable audio backend that aggregates multiple music sources into a single interface, Mopidy is the tool.
| Feature | Details |
|---|---|
| License | Apache-2.0 |
| Protocol | MPD compatible |
| Architecture | Plugin-based (extensions) |
| Local files | Yes (via Mopidy-Local) |
| Spotify | Yes (via Mopidy-Spotify, requires Premium) |
| SoundCloud | Yes (via Mopidy-SoundCloud) |
| YouTube | Yes (via Mopidy-YouTube) |
| Web UI | Via extensions (Iris, Mopidy-Muse, Moped) |
| Mobile clients | Any MPD client (M.A.L.P., MPDroid) |
| Audio output | ALSA, PulseAudio, GStreamer sinks, Snapcast |
Prerequisites
- A Linux server (Ubuntu 22.04+ or Debian 12+ recommended)
- Docker and Docker Compose installed (Docker Compose Basics)
- 256 MB of free RAM
- Your music library accessible on the host filesystem (for local playback)
- Audio hardware connected to the server (for direct playback) or a Snapcast setup (for network playback)
Docker Compose Configuration
Create a directory for Mopidy:
mkdir -p /opt/mopidy/{config,data,music}
Create /opt/mopidy/docker-compose.yml:
services:
mopidy:
image: giof71/mopidy:0.4.23
container_name: mopidy
restart: unless-stopped
ports:
- "6600:6600" # MPD protocol
- "6680:6680" # HTTP / Web UI
volumes:
- ./config:/config
- ./data:/var/lib/mopidy
- ./music:/music:ro
environment:
PUID: 1000
PGID: 1000
TZ: "America/New_York"
# For direct audio output (ALSA), uncomment:
# devices:
# - /dev/snd:/dev/snd
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6680"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
Create the configuration file /opt/mopidy/config/mopidy.conf:
[core]
# Cache and data directories (inside container)
cache_dir = /var/lib/mopidy/cache
config_dir = /config
data_dir = /var/lib/mopidy/data
[logging]
verbosity = 0
[audio]
# Default: software mixer
# For ALSA direct output, change to:
# output = alsasink device=default
output = autoaudiosink
[file]
enabled = true
media_dirs = /music
show_dotfiles = false
excluded_file_extensions =
.cue
.directory
.html
.jpeg
.jpg
.log
.nfo
.pdf
.png
.txt
.zip
[http]
enabled = true
hostname = 0.0.0.0
port = 6680
# Allowed origins for CORS (add your domain)
allowed_origins =
[mpd]
enabled = true
hostname = 0.0.0.0
port = 6600
[local]
enabled = true
media_dir = /music
Start the stack:
cd /opt/mopidy && docker compose up -d
After starting, trigger a local library scan:
docker exec mopidy mopidy local scan
Initial Setup
- Open
http://your-server-ip:6680in your browser - You’ll see the Mopidy HTTP interface — a list of installed web extensions
- If no web extensions are installed, you’ll see a basic JSON API listing
- Install a web client extension (see Configuration below)
The MPD interface is available on port 6600. Any MPD client can connect immediately.
Configuration
Web UI: Install Iris
Mopidy’s most popular web frontend is Iris — a modern, responsive web UI for browsing and playing music:
To add Iris, build a custom Docker image or use a pre-configured image. With the giof71/mopidy image, set the following environment variable:
environment:
MOPIDY_IRIS: "yes"
After restarting, access Iris at http://your-server-ip:6680/iris/.
Spotify Integration
Requires a Spotify Premium account and a Spotify Developer application:
- Create an app at developer.spotify.com
- Note the Client ID and Client Secret
- Add to
mopidy.conf:
[spotify]
enabled = true
username = your_spotify_username
password = your_spotify_password
client_id = your_client_id
client_secret = your_client_secret
bitrate = 320
Note: Mopidy-Spotify uses libspotify, which Spotify deprecated in 2022. The extension still works as of early 2026 but may break without notice. For reliable Spotify integration, consider using Spotifyd alongside Mopidy.
SoundCloud Integration
Add to mopidy.conf:
[soundcloud]
enabled = true
auth_token = your_soundcloud_auth_token
Get your auth token from Mopidy-SoundCloud’s authentication page.
Audio Output Options
| Output | Use Case | Configuration |
|---|---|---|
| ALSA (direct) | Server connected to speakers | output = alsasink device=default |
| PulseAudio | Desktop Linux integration | output = pulsesink |
| Snapcast | Multi-room audio | output = audioresample ! audio/x-raw,rate=48000 ! audioconvert ! wavenc ! filesink location=/tmp/snapfifo |
| HTTP stream | Stream to any browser | Use Mopidy-Stream extension |
For multi-room audio with Snapcast, pipe Mopidy’s output to a Snapcast FIFO:
volumes:
- /tmp/snapfifo:/tmp/snapfifo
Advanced Configuration
Multiple Music Sources
Mopidy’s architecture lets you aggregate multiple sources into a single library:
[file]
enabled = true
media_dirs =
/music|Local Music
/podcasts|Podcasts
/audiobooks|Audiobooks
Each source appears as a separate browse category in the UI.
Scrobbling (Last.fm)
Track your listening history with Last.fm:
[scrobbler]
enabled = true
username = your_lastfm_username
password = your_lastfm_password
Alternatively, use Maloja for self-hosted scrobbling.
Snapcast Multi-Room Setup
For synchronized multi-room audio, add Snapcast alongside Mopidy:
services:
mopidy:
image: giof71/mopidy:0.4.23
container_name: mopidy
restart: unless-stopped
ports:
- "6600:6600"
- "6680:6680"
volumes:
- ./config:/config
- ./data:/var/lib/mopidy
- ./music:/music:ro
- snapfifo:/tmp
environment:
PUID: 1000
PGID: 1000
snapserver:
image: ghcr.io/badaix/snapcast:0.28.0
container_name: snapserver
restart: unless-stopped
ports:
- "1704:1704" # Snapcast stream
- "1705:1705" # Snapcast control
- "1780:1780" # Snapcast web UI
volumes:
- snapfifo:/tmp
volumes:
snapfifo:
Set Mopidy’s audio output to the Snapcast FIFO pipe in mopidy.conf.
Reverse Proxy
Configure your reverse proxy to forward to port 6680 for the web UI:
location / {
proxy_pass http://localhost:6680;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
WebSocket support is required for Iris and other web frontends. See our Reverse Proxy Setup guide.
Backup
Back up the /config and /data directories:
/config/mopidy.conf— all your settings, credentials, extensions/data— local library database, playlists, play history
tar czf mopidy-backup-$(date +%Y%m%d).tar.gz /opt/mopidy/config /opt/mopidy/data
Your music files (/music) should be backed up separately. See our Backup Strategy guide.
Troubleshooting
No audio output
Symptom: Tracks play (progress bar moves) but no sound.
Fix: Check your audio output configuration:
- For ALSA: ensure
/dev/sndis passed to the container and theoutputsetting isalsasink - For PulseAudio: mount the PulseAudio socket into the container
- For Snapcast: verify the FIFO pipe exists at
/tmp/snapfifo
# Test audio inside the container
docker exec mopidy gst-launch-1.0 audiotestsrc ! autoaudiosink
Local library scan finds no tracks
Symptom: mopidy local scan completes but reports 0 tracks.
Fix: Verify:
- Music directory is mounted correctly:
docker exec mopidy ls /music - File extensions are supported (MP3, FLAC, OGG, M4A)
- The
media_dirinmopidy.confmatches the volume mount path - File permissions allow the container user to read the files
MPD clients can’t connect
Symptom: MPD clients (ncmpcpp, M.A.L.P.) fail to connect on port 6600.
Fix: Ensure the MPD section in mopidy.conf binds to 0.0.0.0:
[mpd]
hostname = 0.0.0.0
port = 6600
And port 6600 is mapped in Docker Compose. Restart after changes.
Spotify extension not loading
Symptom: Spotify sources don’t appear in the library.
Fix: Check container logs for Spotify-related errors:
docker logs mopidy 2>&1 | grep -i spotify
Common causes: expired credentials, libspotify compatibility issues, missing client_id/client_secret. Regenerate your Spotify Developer app credentials if expired.
Resource Requirements
| Metric | Idle | Playing (1 stream) | Scanning library |
|---|---|---|---|
| RAM | 80-150 MB | 100-200 MB | 200-400 MB |
| CPU | Minimal | Low | Medium (during scan) |
| Disk | 30 MB (app) | + music library | + library database |
Mopidy is extremely lightweight. It runs comfortably on a Raspberry Pi 4, an N100 mini PC, or alongside other services on any Docker host.
Verdict
If you want a customizable music backend that speaks MPD, plays local files, and optionally aggregates Spotify, SoundCloud, and YouTube into a single interface, Mopidy is the right tool. The extension ecosystem lets you build exactly the music server you want — no more, no less.
The trade-off is assembly. Navidrome gives you a working music server in one docker compose up. Mopidy gives you a foundation that you configure through extensions, config files, and client selection. Choose Mopidy if you already use MPD clients, want multi-room audio with Snapcast, or need to aggregate multiple streaming sources. Choose Navidrome if you want a simple, self-contained music streaming server.
FAQ
Is Mopidy the same as MPD? No. MPD (Music Player Daemon) is a separate project. Mopidy implements the MPD protocol, so MPD clients work with both, but Mopidy is written in Python and supports extensions for streaming services. MPD is C-based and focused on local playback.
Can I use Mopidy without Spotify? Yes. Mopidy-Spotify is an optional extension. Mopidy works with local files only, SoundCloud, YouTube, or any combination of its 100+ available extensions.
Does Mopidy support gapless playback? Yes, through GStreamer. Gapless playback works with local files and most streaming sources. Enable it in the audio configuration if not working by default.
How does Mopidy compare to Navidrome? Navidrome is a standalone Subsonic-compatible music server with a polished web UI. Mopidy is an extensible backend that requires choosing your own frontend. Navidrome is easier to set up; Mopidy is more flexible. See our Navidrome vs Jellyfin comparison for streaming server options.
Related
- Mopidy vs Navidrome: Which Music Server to Self-Host?
- Best Self-Hosted Music Streaming
- How to Self-Host Navidrome
- How to Self-Host Funkwhale
- How to Self-Host Maloja
- Navidrome vs Funkwhale
- Navidrome vs Airsonic
- Self-Hosted Alternatives to Spotify
- Music Server Hardware Guide
- Docker Compose Basics
- Reverse Proxy Setup
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments