这是「Docker 好项目」系列的第 8 期。每期挑一个真正能在自己服务器上跑起来、并且能解决具体问题的项目,给出能直接复制的配置。
你现在听歌用谁?QQ音乐、网易云、Apple Music。曲库里你觉得会永久存在的那几首歌,说下架就下架;会员到期,高音质立刻锁回 128k;更别提歌单里那些冷门歌,哪天歌手解约,链接直接变灰。
其实你硬盘里可能已经躺着几百个 G 的 FLAC——买专辑下的、演唱会扒的、老歌挖的,就是没个顺手的入口听。
Navidrome 干的就是这件事:把自己手里的音频文件变成一个私人流媒体服务。Go 写的单二进制,内置 Web 播放器,兼容 Subsonic API——意味着 iOS/Android 上几十个成熟的第三方客户端都能直接连它。GPLv3 开源,23k+ stars,写这篇时最新版 v0.64.0(2026-09-12 发布),修复了一整批安全问题。

它到底能干什么
- 流式播放自己的音乐库:网页端就是全功能播放器,专辑墙、歌手页、随机推荐、搜索、播放队列都有,不用装任何客户端
- Subsonic API 兼容:这是它最值钱的特性。Android 上的 Symfonium、Ultrasonic,iOS 上的 play:Sub、Amperfy,桌面端的 Feishin、Sonixd,全都拿服务器地址 + 用户名密码直接连
- 多用户:给家里人各开一个账号,各自的播放记录、收藏、歌单互相独立;还能按库分配权限(你的歌单不想让孩子看到就单独建个库)
- 多库管理(0.62+):音乐一个库、有声书/播客一个库,挂载几个目录就是几个库
- 歌词与分级评分:支持内嵌歌词和 .lrc/.ttml 等外挂歌词,0.63 起连逐字卡拉 OK 时间轴都能读
- 分享链接:可以把单曲/专辑生成外链发给朋友(0.64 修掉了一个越权漏洞,建议直接上最新版)
- 实时转码:内置 ffmpeg,手机在外用流量时按码率转码,不吃流量套餐
它不做的是:不做音乐管理器(刮削改名整理文件交给 beets、MusicTag 这类工具)、不提供任何在线音源、不能像 Jellyfin 那样管电影和图片。它就是一个纯粹的音频流媒体服务。

部署前准备
- 内存:空载 50MB 上下,1 核 512MB 的小鸡都带得动,是这系列目前最轻的一个
- 音乐文件:得自己有音频文件。按
歌手/专辑/曲目的目录结构放最省心,标签(ID3)写得越全,界面识别越准 - 转码依赖:官方镜像里已经带好了 ffmpeg,不用额外装
- 端口:默认 4533
- 数据库:默认 SQLite,存在
/data里,无需外接数据库
docker run 一行版
先跑起来感受一下:
docker run -d \
--name navidrome \
--restart unless-stopped \
--user 1000:1000 \
-p 4533:4533 \
-v /opt/navidrome/data:/data \
-v /opt/music:/music:ro \
deluan/navidrome:0.64.0
--user 1000:1000先用id -u、id -g查一下你自己的 UID/GID,换成本机的值。为什么必须写,看下面「配置项」表格。
浏览器打开 http://服务器IP:4533,注册第一个账号即管理员。
国内拉 Docker Hub 超时的话,换 ghcr 的同一份镜像(官方双仓库发布,内容一致):
docker run -d \
--name navidrome \
--restart unless-stopped \
--user 1000:1000 \
-p 4533:4533 \
-v /opt/navidrome/data:/data \
-v /opt/music:/music:ro \
ghcr.io/navidrome/navidrome:0.64.0
docker-compose 推荐版
正式用建议这样部署。新建目录和文件:
mkdir -p /opt/navidrome/data && cd /opt/navidrome
新建 docker-compose.yml:
services:
navidrome:
image: deluan/navidrome:0.64.0
container_name: navidrome
restart: unless-stopped
user: "1000:1000"
ports:
- "4533:4533"
volumes:
- ./data:/data
- /opt/music:/music:ro
environment:
ND_LOGLEVEL: info
ND_SESSIONTIMEOUT: 168h
ND_DEFAULTLANGUAGE: zh-Hans
ND_ENABLETRANSCODINGCONFIG: "true"
ND_ENABLEINSIGHTSCOLLECTOR: "false"
ND_SCANNER_SCHEDULE: "1h"
# ND_BASEURL: ""
# ND_BACKUP_PATH: /data/backup
# ND_BACKUP_SCHEDULE: "0 0 4 * * *"
# ND_BACKUP_COUNT: 7
启动:
docker compose up -d
docker compose logs -f navidrome
日志里看到监听 4533 就成了。第一次启动会自动全库扫描(ND_SCANNER_SCANONSTARTUP 默认开启),大库要等一会儿。
每个配置项为什么这么写
| 配置 | 说明 |
|---|---|
deluan/navidrome:0.64.0 |
只能写完整版本号。官方镜像的 tag 规则只有 0.64.0 这种全量版、PR 号和 develop,latest 和 :0.64 这种主次版本 tag 要么没有要么偏开发向——我已经在 registry 里逐个验证过,0.64 是 404。钉全量版本号是唯一稳妥写法 |
user: "1000:1000" |
Navidrome 需要 /data 可写、/music 可读,且都归这个 UID:GID 管。注意 PUID/PGID 环境变量对它无效——那是 linuxserver.io 系镜像的约定,官方镜像根本不认,写了也是白写(这是新手第一大坑)。官方文档明确建议用 user: 指令而不是去掉它让容器以 root 跑 |
./data:/data |
SQLite 数据库、转码缓存、封面缓存全在这里,这是唯一要备份的目录。放 compose 同目录,搬家整目录拷走 |
/opt/music:/music:ro |
音乐库只读挂载。Navidrome 从不改音乐文件,:ro 是一道保险:容器被攻破也写不了你的曲库。镜像里默认 ND_MUSICFOLDER=/music,所以路径必须挂到 /music |
"4533:4533" |
对家族多人、手机局域网直连友好的写法。如果你的实例只打算自己通过 HTTPS 反代访问,可改成 "127.0.0.1:4533:4533" 收紧(参考第 7 期 Memos 的做法) |
ND_SESSIONTIMEOUT: 168h |
登录态有效期,默认 48h——手机客户端两天要重新登一次很烦。个人自用放宽到一周,多人共用或公网暴露的实例保持默认 |
ND_DEFAULTLANGUAGE: zh-Hans |
界面默认简体中文。必须区分大小写,写 zh-hans 或 zh-HANS 都不生效,对应的是源码 resources/i18n 里的文件名 |
ND_ENABLETRANSCODINGCONFIG: "true" |
默认 false,用户改不了自己的转码码率。打开后每个人能在播放器里自选(如手机流量时切 96k),多用户实例建议开 |
ND_ENABLEINSIGHTSCOLLECTOR: "false" |
匿名使用统计上报,默认开启。自托管图的就是数据不出门,关掉 |
ND_SCANNER_SCHEDULE: "1h" |
定时全库扫描周期,默认是 0(禁用)——因为日常增量靠文件监听(watcher)自动触发。挂 1 小时兜底一次,防止监听漏事件(某些网络挂载上 watcher 不可靠)。这里要敲黑板:老教程里写的 ND_SCANSCHEDULE 是改名前的旧变量,现在是「未识别配置项」,0.64 起启动时会明确告警,不会静默生效 |
ND_BASEURL |
反代到子路径(如 https://域名/music)时才需要设,见下文。默认注释掉——根路径反代和直连都不要设它,设了会导致资源路径全错 |
ND_BACKUP_PATH / SCHEDULE / COUNT |
0.60+ 内置的数据库自动备份:路径、cron 周期、保留份数。三件套一起配才生效,默认全关。不想用内置的可以走下文的 tar 方案,二选一即可 |
配置项远不止这些,完整清单在官方 options 文档里,命名规律是「配置文件里的驼峰 + ND_ 前缀」。
1Panel 怎么搞
Navidrome 目前不在 1Panel 应用商店里,所以走容器 → 编排 → 创建编排这条路:把上面的 docker-compose.yml 原样贴进去,数据目录选在 /opt/navidrome,一键启动。后续升级、看日志、改配置都在面板里点。
音乐文件放哪:
- 华为云主机:直接
/opt/music建目录传文件,注意云盘容量和流量 - 飞牛 NAS 这类有现成曲库的:把 NAS 上的音乐目录挂进容器即可(compose 里
-v /vol1/music:/music:ro换成你的实际路径),不用复制一份
顺手在 1Panel 计划任务里加一条容器每日重启 or 数据库备份(见下文备份节)。
首次访问与最小可用配置
浏览器打开 http://服务器IP:4533,注册第一个账号——第一个注册的用户自动是管理员。
进后台(右上角头像 → Users)做三件事就算最小可用:
- 关掉公开注册:把「Allow new users」相关选项关掉,否则知道地址的人都能来开账号
- 建家庭成员账号:给要听歌的人各开一个,密码单独设——Subsonic 客户端就是拿这个账号登录的
- 确认曲库已被扫描:首页能刷出专辑就 OK;没出来先看日志是不是
/music权限问题(报permission denied就是user:和目录属主没对齐)
之后手机装一个 Subsonic 客户端,填 http://服务器IP:4533 + 账号密码即可。出门在外就把域名反代配上(见下节),客户端地址换成 HTTPS 域名。
联动与告警
Navidrome 不是监控系统,没有告警概念,但有几个往外接的口子:
Prometheus 指标(第 1 期 Uptime Kuma 用户看这里):
environment:
ND_PROMETHEUS_ENABLED: "true"
ND_PROMETHEUS_PASSWORD: "换成强密码"
开启后 http://127.0.0.1:4533/metrics 带密码可拉取,接 Prometheus/Grafana 看在线人数、扫描时长、转码耗时。密码不设就是裸奔接口,所以两行要一起出现。最轻量的做法是让 Uptime Kuma 加一个 HTTP(s) 监控打 4533,挂了发通知。
听歌记录同步:支持 Last.fm 和 ListenBrainz 的 scrobble,在个人设置里授权即可,你的播放历史会同步过去,也能反哺「相似歌曲」推荐。
Smart Playlists:用规则语法定义智能歌单(如「最近添加 + 星级 ≥ 4」),服务端定期自动刷新,客户端无需任何插件。
反向代理与 HTTPS
Navidrome 的 Web 端没有 WebSocket 依赖,普通 HTTP 反代即可,比前几期都省心。
用第 2 期的 Nginx Proxy Manager:新建 Proxy Host,域名填 music.你的域名,Forward 到 127.0.0.1:4533(或局域网主机 IP),SSL 页签一键签证书。
用 1Panel 更直接:网站 → 反代 → 新建,代理地址 http://127.0.0.1:4533,然后在网站设置里签 Let's Encrypt 证书。
两个注意事项:
- 根路径反代(
https://music.域名→ 整站)什么都不用改,最推荐。子路径反代(https://域名/music)必须设ND_BASEURL=/music并重启容器,否则页面白屏、静态资源 404 - 分享链接域名:开了分享功能的话,把
ND_SHAREURL设成你的对外 HTTPS 地址,生成的分享链接才是能直接点开的 - 0.64 修了一个「伪造
X-Forwarded-For绕过登录限速」的漏洞,并且现在按可信客户端 IP 计数——反代场景下确保反代传递真实来源头,登录爆破的限速才是准的
踩坑清单
PUID/PGID没有任何效果:官方镜像不认这组变量。要么user: "1000:1000"+ 目录属主对齐,要么别怪界面里曲库是空的/data不可写:容器起不来,日志报unable to open database file。chown -R一下数据目录就行;千万别用「去掉user:让它以 root 跑」来修——官方文档明确不建议- 老教程的
ND_SCANSCHEDULE:0.60 重构成ND_SCANNER_SCHEDULE(多了个 R),0.64 起会对未识别配置项打告警。发现日志里出现unknown option就去对一遍文档 - 配置时长不能写负数:0.64 起启动时校验时长格式,
-1h这种以前被默默容忍的值现在会直接拒绝启动 - 0.64 升级会重写所有 ID:内部 ID 统一重编码成 128 位格式,升级前必须备份数据库;客户端本地缓存的离线下载可能要重新同步。这是本期最大的迁移坑,跨大版本前先看 Release Notes 的 Breaking Changes
- 手机连不上但网页正常:九成是客户端填了
http://而服务已切 HTTPS,或反向代理没放行/rest/路径(Subsonic API 走这条)。NPM 默认全放行,自写 nginx 规则的留意 - 转码 CPU 占用高:FLAC 转 opus 是 CPU 活,1 核小鸡上多人同时播会卡。把
ND_TRANSCODING_MAXCONCURRENT设成 2 限并发,或者让局域网用户用 raw 模式直出 - 国内拉镜像:换
ghcr.io/navidrome/navidrome:0.64.0,官方同一套 CI 推双仓库
备份
要备份的只有 /data 里的 navidrome.db(音乐文件本身在你自己的曲库目录,另有备份策略)。最简单的 tar 方案:
cd /opt/navidrome
docker stop navidrome
tar czf navidrome-backup-$(date +%F).tar.gz data/
docker start navidrome
恢复就是解包回去再启动:
cd /opt/navidrome && docker stop navidrome
tar xzf navidrome-backup-2026-09-21.tar.gz
docker start navidrome
更优雅的是用 0.60+ 的内置备份,挂到 compose 里让容器自己干:
environment:
ND_BACKUP_PATH: /data/backup
ND_BACKUP_SCHEDULE: "0 0 4 * * *"
ND_BACKUP_COUNT: 7
每天凌晨 4 点压缩一份数据库到 /data/backup,自动滚动保留 7 份。注意备份存在 /data 里,真要容灾还是得把这个目录加进整盘备份(1Panel 的备份计划里把 /opt/navidrome 加上即可)。
小结
Navidrome 是这系列目前资源占用最低、部署最快的一期:一个容器、一个端口、一个数据目录,五分钟把自己变成流媒体服务商。而且它站在 Subsonic 生态上,客户端随便挑,不绑架你。
适合:手里有音频文件想集中管理的、家里人各自用手机听歌的、被云音乐下架和会员体系恶心到的。 不适合:完全没有本地音乐文件、指望它替代 QQ 音乐在线曲库的;想顺便管电影和照片的(那是 Jellyfin/Immich 的活儿,见第 4 期)。
下期继续聊另一个 Docker 项目。
项目地址:https://github.com/navidrome/navidrome 官方文档:https://www.navidrome.org/docs/