Skip to content

MusicBrainz mirror

Raphael Vael edited this page Aug 11, 2026 · 2 revisions

Local MusicBrainz mirror

PMDA works out of the box against the public MusicBrainz API, but that API is rate-limited to about one request per second. On a large or messy library, identification spends most of its time waiting. A local mirror removes the limit entirely: on the reference production setup, lookups answer in 30-70 ms and the scanner runs at full speed. PMDA uses the mirror for both direct lookups and search, so the search index (Solr) is required — a database-only mirror is not enough.

This page describes the exact topology PMDA's own production setup runs.

Requirements

Resource What to plan
Storage ~200 GB on fast storage (SSD/NVMe strongly recommended). A loaded mirror is ~60 GB of PostgreSQL plus ~110 GB of Solr index, and it grows slowly.
RAM 8 GB minimum for the mirror stack, 16 GB comfortable (PostgreSQL shared buffers + Solr).
Software Docker with the compose plugin, git.
Time The initial import runs for several hours (dump download, database import, search indexing) — overnight is realistic. It is a one-time cost.
Network ~50 GB of downloads for the initial data dumps.

Storage placement matters. Put the mirror's data on a real disk path you chose, never inside Docker's own image file (docker.img on Unraid): the mirror will fill it. PMDA's quick-start docker run now ships a dedicated /musicbrainz-mirror mount for exactly this purpose. On Unraid, use a cache (NVMe) path such as /mnt/cache/musicbrainz-mirror.

Step 1 — install the official MusicBrainz stack

The mirror is the official musicbrainz-docker project from MetaBrainz — PMDA does not bundle it, it talks to it.

git clone https://github.com/metabrainz/musicbrainz-docker.git
cd musicbrainz-docker

Enable the search index (required by PMDA) and the published web port:

admin/configure add live-indexing-search publishing-all-ports

Step 2 — put the data on the storage you chose

Create a compose override so the volumes are real bind mounts instead of anonymous Docker volumes. Save this as local/compose/data-bind-mounts.yml (adapt the two roots to your paths):

volumes:
  pgdata:
    driver: local
    driver_opts: {type: none, o: bind, device: /srv/pmda/musicbrainz-mirror/pgdata}
  solrdata:
    driver: local
    driver_opts: {type: none, o: bind, device: /srv/pmda/musicbrainz-mirror/solrdata}
  dbdump:
    driver: local
    driver_opts: {type: none, o: bind, device: /srv/pmda/musicbrainz-mirror/dbdump}
  solrdump:
    driver: local
    driver_opts: {type: none, o: bind, device: /srv/pmda/musicbrainz-mirror/solrdump}

Create the four directories, then register the override:

mkdir -p /srv/pmda/musicbrainz-mirror/{pgdata,solrdata,dbdump,solrdump}
admin/configure add local/compose/data-bind-mounts.yml

Step 3 — import the data and start

sudo docker compose build
sudo docker compose run --rm musicbrainz createdb.sh -fetch
sudo docker compose up -d

createdb.sh -fetch downloads the current data dumps and imports them — this is the hours-long part. Once the stack is up, load the search indexes from the pre-built dumps (the fast route; the reference setup used exactly this):

sudo docker compose run --rm musicbrainz fetch-dump.sh search
sudo docker compose run --rm search load-search-indexes.sh

(The command names can move between musicbrainz-docker releases — if either is not found, follow the "Search indexes" section of the musicbrainz-docker README you cloned; the live sir reindex route works too, it is just much slower.)

When it finishes, http://YOUR_SERVER_IP:5000 shows a working MusicBrainz web page served from your own copy.

Replication (keeping the mirror current) is optional and works fine set to weekly or even less — PMDA re-verifies matches continuously anyway. See the replication-cron option in the musicbrainz-docker README if you want it.

Step 4 — point PMDA at it

  • Existing install: Settings > Metadata providers > MusicBrainz > enable Local mirror, set the URL to http://YOUR_SERVER_IP:5000, give it a name. That is all.
  • Fresh install: finish the first-run wizard normally first (the wizard covers folders and workflow, not providers), then do the same thing in Settings. The mirror can be added at any time — before, during or after your first scan.

PMDA probes the mirror and tells you what it sees: the System page reports "MusicBrainz mirror reachable" with the measured latency when everything is right, and falls back to the public API automatically whenever the mirror is down — enabling the mirror can never break matching.

Verifying it works

  • The MusicBrainz panel in Settings shows the mirror as enabled with your URL.
  • The System / runtime page reports the mirror healthy with a latency in the tens of milliseconds.
  • Scans stop pacing at ~1 lookup per second.

Troubleshooting

  • PMDA says the mirror is unreachable: check the URL is reachable from INSIDE the PMDA container (docker exec pmda curl -s http://IP:5000), not just from your desktop. Use the server's LAN IP, not localhost.
  • Search returns nothing while lookups work: the Solr index has not been built (or the live-indexing-search option is missing). Re-run step 3's index loading.
  • Disk filled up: the data landed inside Docker's image file instead of your bind mounts — re-check step 2 (the override must be added BEFORE the first docker compose up, otherwise delete the anonymous volumes and re-import onto the binds).

Clone this wiki locally