New releases
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Editorial pickMusic
Navidrome turns a folder of music into a personal streaming service: it reads tags and artwork, remembers your listening history, and serves the collection to the browser and to dozens of mobile apps through the Subsonic API. One container, an SQLite database, no subscription.
Navidrome is a music server for a collection that lives as files. It reads tags and artwork, builds a library by artist and album, remembers ratings, playlists, and listening history, and streams to a browser or a phone. It fits anyone who spent years collecting music and would rather not watch tracks vanish from a subscription catalogue.
The key feature is the Subsonic API: the project ships no mobile apps of its own, but there are dozens of compatible clients, from Symfonium and substreamer on Android to play:Sub on iOS and Feishin on the desktop. The server is written in Go, fits in a single container, and runs on hardware as small as a Raspberry Pi.
The recipe mounts the music directory read-only and keeps the database, artwork,
and history in a separate Docker volume. The reliable level is not claimed:
Navidrome uses embedded SQLite, and the recipe adds no monitoring and no
resource limits.
Anonymous usage statistics are disabled in this recipe (
NAVIDROME_INSIGHTS=false). One variable turns them back on if you want to support the project with data.
The container runs without privileged, host networking, or Docker socket
access, and uses no-new-privileges; only the web port is published, and only on
127.0.0.1. The music library is mounted read-only, so the server cannot modify
or delete your files.
The main risk is the first start: until the administrator account exists, the
setup form is open to whoever reaches it, so the port must stay unexposed until
you have created it. The second is the
protocol itself: the Subsonic API sends credentials with every request, and some
clients still send the password in clear text, so the server may only be
published over HTTPS. The container runs as root, as in the upstream image; if
that matters, set user: and adjust volume ownership yourself.
The recipe image is scanned with Trivy and has no critical findings. That is what you would expect from an image made of Alpine plus a single statically linked Go binary.
These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Result of a dedicated Docker image scan, not a Compose configuration check.
A new major version is found by comparing version numbers. A compatibility verdict is entered by hand after reading the release notes and the migration steps.
Upstream Compose changes relative to the verified recipe.
Pinned image tags checked for newer versions.
From observation to action
The recipe already pins the latest known release. The steps below show the evidence retained for that version.
v0.63.2v0.63.2Open this release on GitHub ↗ The link is evidence to review, not proof of compatibility.
The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.
No image-tag change is currently planned.
Change the tag and restart. Release-specific migration steps still come from the release notes and installation guide.
No version change is currently planned. The recipe includes a backup procedure. Restore has been tested.
An exact Fully verified check for this target was recorded on 2026-08-31.
The status shows how fully the published recipe meets each level's requirements.
A minimal setup for a local network or access through a VPN.
The recipe covers every requirement at this level.
A public deployment with protected access and backups.
The recipe covers every requirement at this level.
A setup designed for predictable operations and observability.
You still need to add: separate database, external monitoring, cpu and memory limits.
Tailored to your server
Answer five questions and download a ready-to-run Navidrome bundle.
Screenshots have not been added yet.
Read the full guide first: it explains external access, backups, and data locations.
cp .env.example .envdocker compose up -ddocker compose psThis recipe needs 1 CPU core, 256 MB of RAM, and 2 GB of disk for the server itself; 512 MB of RAM is recommended. This is a conservative estimate for the recipe: upstream publishes no formal minimum. Count storage for the music separately, plus a few percent for the artwork cache. You need Ubuntu 22.04+ or Debian 12+ with Docker Engine and Docker Compose v2.24+.
docker --version
docker compose version
Navidrome reads tags, not file names, so filled-in Artist, Album, Title,
and track number matter most. The directory layout is up to you, but
artist/album is the most convenient:
/srv/music/Artist Name/Album Name (2019)/01 Track.mp3
/srv/music/Artist Name/Album Name (2019)/cover.jpg
Navidrome takes artwork from the tag or from a cover.jpg, folder.jpg, or
front.jpg file next to the tracks. MP3, FLAC, OGG, Opus, M4A, WavPack, and
other formats understood by the bundled ffmpeg are supported.
mkdir -p ~/services/navidrome
cd ~/services/navidrome
cp .env.example .env
chmod 600 .env
sed -i "s|^NAVIDROME_MUSIC_LOCATION=.*|NAVIDROME_MUSIC_LOCATION=/srv/music|" .env
NAVIDROME_VERSION pins the image; NAVIDROME_PORT sets the local port;
NAVIDROME_MUSIC_LOCATION is the music directory, mounted read-only;
NAVIDROME_DATA_VOLUME is the volume with the database, artwork, and listening
history; NAVIDROME_SCAN_INTERVAL controls automatic scans;
NAVIDROME_LOG_LEVEL and NAVIDROME_SESSION_TIMEOUT cover logging and session
lifetime; NAVIDROME_BASE_URL is only needed when the service is published
under a subpath; NAVIDROME_INSIGHTS controls anonymous usage statistics and is
off by default; TZ sets the time zone.
The administrator form has no password: whoever opens it first owns the server. Run the first start over localhost or an SSH tunnel.
docker compose pull
docker compose up -d
docker compose ps
ssh -L 4533:127.0.0.1:4533 user@server.example
Open http://localhost:4533 and set a username and password. The first scan
starts right after; the container log shows how many tracks were imported:
docker compose logs --tail=50 navidrome | grep -i scanner
The administrator creates the other users under Users. Mobile and desktop clients are third-party: they connect to the same address through the Subsonic API.
On a VPS keep the 127.0.0.1 bind, block port 4533 from outside, and publish the
service only through an HTTPS reverse proxy. Check the state and the API:
docker compose up -d
docker compose ps
curl --fail http://127.0.0.1:4533/ping
curl --fail "http://127.0.0.1:4533/rest/ping?v=1.16.1&c=check&f=json"
The second request answers with an authentication error — that is expected: it confirms the Subsonic API is serving and reports the server version.
Without TLS use an SSH tunnel or a VPN. If the reverse proxy runs on another host
in a trusted LAN, replace 127.0.0.1 in compose.yaml with the server’s LAN
address and restrict the port to the proxy address in the firewall. Do not
publish Navidrome on 0.0.0.0 without restrictions: the Subsonic API sends
credentials with every request.
Replace music.example.com with your single domain in the file you pick from
proxy/. proxy/Caddyfile obtains a certificate automatically;
proxy/nginx.conf expects a Certbot certificate; proxy/traefik.yaml uses the
letsencrypt resolver. For Traefik in a container, replace 127.0.0.1 with a
host gateway it can reach.
The Nginx sample disables response buffering: without it, seeking inside a track
stutters. If the service is published below the domain root, set the same
subpath in NAVIDROME_BASE_URL, otherwise the web interface cannot find its own
files.
curl --fail https://music.example.com/ping
chmod +x backup.sh restore.sh
./backup.sh
The script stops the container, archives the /data volume, and starts it again.
Stopping is required: the SQLite database copies consistently only from a
stopped server. The archive holds users, playlists, ratings, listening history,
and the artwork cache.
The music is not in the archive: those are your own files and need their own copy.
Navidrome also has its own mechanism — docker compose exec navidrome /app/navidrome backup create --datafolder /data snapshots the database without
stopping the server. It is handy before an update, and it ends up inside the
copy that backup.sh makes.
Restoring replaces the contents of /data with the selected archive:
./restore.sh ./backups/navidrome-YYYYMMDDTHHMMSSZ.tar.gz
docker compose ps
curl --fail http://127.0.0.1:4533/ping
Before replacing anything the script takes a safety copy of the current data. The
music is untouched, but the paths in the restored database must match the
current /music mount, otherwise tracks are marked as missing until the next
scan.
Take a backup and read the release notes. Change only the pinned
NAVIDROME_VERSION, then run:
./backup.sh
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 navidrome
Database migrations run the first time a new version starts. Larger updates sometimes require a full library rescan; the release notes say so when they do.
Downgrades are not supported: after a migration the older image cannot open the
database. Restore the pinned NAVIDROME_VERSION in .env and restore the
archive taken before the update:
docker compose pull
./restore.sh ./backups/navidrome-before-update.tar.gz
docker compose up -d
Ratings and listening history created after the update are not in that archive.
docker compose down removes the container but keeps the database. Complete,
irreversible removal after verifying a backup:
docker compose down
docker volume rm navidrome-data
rm -rf ~/services/navidrome
The NAVIDROME_MUSIC_LOCATION directory stays untouched: the recipe mounts it
read-only and never deletes from it.
Sources: Docker installation, configuration options, artwork and tags, backup and restore, anonymous statistics, and security recommendations.
Check that the directory is visible inside the container and that the scan finished:
docker compose exec navidrome ls -la /music
docker compose logs --tail=100 navidrome | grep -i scanner
An empty result with a visible directory almost always means missing tags:
Navidrome builds the library from Artist, Album, and Title, not from file
names. Inspect the tags of a single file with the built-in command:
docker compose exec navidrome /app/navidrome inspect "/music/path/to/file.mp3"
By default the recipe scans once a day (NAVIDROME_SCAN_INTERVAL). Trigger a
scan immediately from the web interface with the refresh button, or run:
docker compose exec navidrome /app/navidrome scan --datafolder /data
Artwork comes from the tag or from a cover.jpg, folder.jpg, or front.jpg
file next to the tracks. Make sure the file sits in the album directory and is
readable. The artwork cache lives in the /data volume and rebuilds itself.
This happens with compilations that have no Album Artist tag. Set the same
Album Artist on every track of the album (for example Various Artists) and
run a rescan.
The client needs the server address without /app, a username, and a password.
Check that the API answers:
curl --fail "https://music.example.com/rest/ping?v=1.16.1&c=check&f=json"
An authentication error means the API works. No answer at all points at the
reverse proxy or at NAVIDROME_BASE_URL.
That happens when Navidrome is published under a subpath and NAVIDROME_BASE_URL
is not set. Use the same path as in the reverse proxy and restart the container.
The reverse proxy is buffering the response. Nginx needs proxy_buffering off,
which the sample in proxy/ already has. Caddy and Traefik stream without
buffering.
Change it with a command inside the container:
docker compose exec navidrome /app/navidrome user edit --datafolder /data
The command is interactive, so run it from a terminal with a TTY.
docker compose logs --tail=200 navidrome | grep -i "migration\|error"
Downgrades are not supported: the only way back is restoring the archive taken before the update.
Fossary is an independent informational catalog and is not affiliated with the developers of the listed applications. We collect information from public sources and verify published recipes, but we do not develop, distribute, or control these applications.
A listing or validation status is not a requirement, endorsement, or personal recommendation to use an application. You decide whether it is suitable and use it at your own risk. We do not warrant an application's security, availability, or fitness for purpose and, to the extent permitted by law, are not liable for resulting loss or damage. Review its license, security settings, data processing, and backup procedures before installation.