mStream 6.32.0 配置参数详解

mStream 6.32.0 全量配置参数详解:config.json 五大类键逐项说明与实测回显、users 段 PBKDF2 口令与 salt 生成、CLI 启动参数矩阵、管理 API 运行时改参

mStreammStream音乐流媒体自托管媒体服务器Nodejs2026/10/29

mStream 6.32.0 配置参数详解

目标:本文系统梳理 mStream 6.32.0 的全部配置入口——config.json 持久化配置(五大类键逐项说明,附实测回显)、启动参数(--help 实测全量)、管理 API 运行时改参,并沉淀 salt 校验、PBKDF2 口令、迁移标记等实测排障结论。全部输出已在 Ubuntu 24.04 服务器(mStream 6.32.0、配置目录 /srv/mstream/config、端口 8155)实测通过。

一、环境信息

  • 操作系统:Ubuntu 24.04(x86_64)
  • mStream:6.32.0(mstream -V 实测输出 6.32.0)
  • 配置文件:/srv/mstream/config/config.json(实测 50 行)
  • 元数据库:/srv/mstream/config/db/mstream.db(SQLite,含 FTS5)
  • 服务端口:8155(进程内监听 3000)
  • 曲库:/srv/mstream/music,虚拟路径名 music(6 首 mp3、2 张专辑)
  • 演示账号:admin / q1w2e3r4(管理员)、root / q1w2e3r4(普通用户示例)

二、前置条件

  1. mStream 已部署并可登录(部署过程见《mStream 6.32.0 Docker Compose 部署指南》)。验证服务可访问:
curl -s -o /dev/null -w 'GET /login/ -> %{http_code}\n' http://localhost:8155/login/

实测输出:

GET /login/ -> 200
  1. 管理员账号可用(本文示例用 admin / q1w2e3r4),需要时先获取 API 令牌(运行时改参与管理 API 部分用到):
TOKEN=$(curl -s -X POST http://localhost:8155/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4"}' \
  | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")
echo "${TOKEN:0:24}..."

实测输出:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

三、参数查看与修改方式

mStream 6.32.0 的配置有三层入口,优先级与生效方式不同,逐一实测说明。

3.1 直接查看 config.json

cat /srv/mstream/config/config.json

实测输出(完整照抄,测试环境自动生成值):

{
  "port": 3000,
  "secret": "mstream-6320-evidence-secret-key-2026",
  "writeLogs": true,
  "noUpload": false,
  "scanOptions": {
    "skipImg": false,
    "scanInterval": 2,
    "pause": 50,
    "saveInterval": 250,
    "bootScanDelay": 5
  },
  "storage": {
    "albumArtDirectory": "/config/album-art",
    "dbDirectory": "/config/db",
    "logsDirectory": "/config/logs",
    "waveformCacheDirectory": "/config/waveform-cache"
  },
  "folders": {
    "music": { "root": "/music" }
  },
  "users": {
    "admin": {
      "password": "kRwJgrHolLWXdZp4fXOepkx9ODFTsddjYrOeO1uWNlY=",
      "vpaths": ["music"],
      "salt": "k7iA5oyj/jAkEi3KVWYEZQ==",
      "admin": true
    }
  },
  "setupComplete": true,
  "iroh": {
    "secretKey": "o7LPrREhDSFkAjUHT1ysPZ7jUQogzZJtOiem1dKtWUQ="
  },
  "dlna": {
    "uuid": "b2bfa305-cec8-43c6-959b-d7b1fb214621"
  },
  "discovery": {
    "mdns": {
      "instanceId": "2131c37a-58ec-4b0f-986d-9ad73c072852"
    }
  },
  "federation": {}
}

要点:port/storage 是服务化部署时按挂载点自动归一的形态(进程内固定 3000,对外映射在部署层做);setupComplete、iroh、dlna、discovery、federation 五个键由服务首次成功启动自动生成,手工无需维护;users 段仅作为首启向 SQLite 的一次性迁移源(迁移后账号以数据库为准,详见 5.4)。

3.2 修改方式一:编辑文件 + 重启

改完 config.json 后重启服务进程生效。实测修改 scanOptions.scanInterval(1.5 → 2)后重启,用管理 API 确认生效(见 3.3 的 GET 回显 scanInterval: 2)。

3.3 修改方式二:管理 API 运行时改参(推荐用于扫描参数)

扫描与音频分析参数支持免重启在线修改,改完自动写回 config.json。先查询当前值:

curl -s -H "x-access-token: $TOKEN" http://localhost:8155/api/v1/admin/db/params

实测输出(完整照抄):

{"skipImg":false,"scanInterval":2,"pause":50,"saveInterval":250,"bootScanDelay":5,"ignoreDotFiles":false,"ignoreDotFolders":false,"artistSplitExceptions":[],"watcherEnabled":false,"watcherWait":10,"compressImage":true,"scanCommitInterval":25,"scanThreads":0,"generateWaveforms":true,"analyzeBpm":true,"analyzeBpmPerRun":200,"analyzeBpmMethod":"multifeature","analyzeBpmWindowSec":60,"analyzeAcoustid":false,"acoustidPerRun":200,"acoustidApiKey":"BOJOtheMHU","acoustidApiUrl":"https://api.acoustid.org/v2/lookup","collectDiscoveryData":true,"discoveryModel":"effnet-discogs","discoveryPerRun":50,"embeddingRuntime":"auto","autoAlbumArt":true,"autoAlbumArtMode":"missing","autoAlbumArtWriteToFolder":false,"autoAlbumArtPerRun":100,"albumArtWriteToFolder":false,"albumArtWriteToFile":false,"albumArtServices":["musicbrainz","itunes","deezer"],"albumArtPriority":"metadata"}

修改并验证写回:

curl -s -X POST -H "x-access-token: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"scanInterval":2}' http://localhost:8155/api/v1/admin/db/params/scan-interval

实测输出:

{}
grep scanInterval /srv/mstream/config/config.json

实测输出:

"scanInterval": 2,

返回 {} 且配置文件回显新值,说明「API 修改 → 持久化写回」链路生效。

3.4 修改方式三:Web 管理面板

浏览器登录后访问 http://<服务器IP>:8155/admin,管理面板提供与 3.3 相同的参数项(扫描间隔、波形、BPM 分析、封面服务等),本质调用同一组 admin API,适合手工调参;批量脚本场景用 3.3 的 curl 方式。

四、参数总览

config.json 顶层键一览(实测 50 行配置归纳,按用途分五类):

类别键类型/默认作用
服务基础port整数 / 3000服务进程监听端口
服务基础secret字符串 / 随机JWT 签名密钥,更换后所有已发 token 失效
服务基础writeLogs布尔 / true是否写日志文件到 logsDirectory
服务基础noUpload布尔 / false关闭 Web 上传入口
服务基础setupComplete布尔 / 自动初始化向导完成标记(自动生成)
曲库扫描scanOptions.skipImg布尔 / false扫描时跳过图片文件
曲库扫描scanOptions.scanInterval小时 / 1.5定时全量扫描间隔(实测改为 2)
曲库扫描scanOptions.pause毫秒 / 50扫描每文件间暂停,降低 IO 峰值
曲库扫描scanOptions.saveInterval文件数 / 250每处理 N 个文件提交一次数据库事务
曲库扫描scanOptions.bootScanDelay秒 / 5启动后延迟多少秒开始首扫
存储路径storage.dbDirectory路径 / <config>/dbSQLite 主库目录
存储路径storage.albumArtDirectory路径 / <config>/album-art专辑封面缓存目录
存储路径storage.logsDirectory路径 / <config>/logs日志目录
存储路径storage.waveformCacheDirectory路径 / <config>/waveform-cache波形缓存目录
曲库与用户folders.<名>.root路径 / 无默认曲库目录到虚拟路径(vpath)的映射
曲库与用户folders.<名>.type字符串 / music库类型(music)
曲库与用户folders.<名>.followSymlinks布尔 / false是否跟随符号链接
曲库与用户users.<名>.password字符串 / 必填PBKDF2-SHA512 口令哈希(见 5.3)
曲库与用户users.<名>.salt字符串 / 必填16 字节 base64 盐值(缺失无法启动)
曲库与用户users.<名>.admin布尔 / false是否管理员(实测置 true 后管理 API 可用)
曲库与用户users.<名>.vpaths数组 / 必填该用户可访问的 vpath 列表
子系统(自动生成)iroh.secretKey字符串 / 随机P2P 联邦节点密钥
子系统(自动生成)dlna.uuidUUID / 随机DLNA 设备标识
子系统(自动生成)discovery.mdns.instanceIdUUID / 随机mDNS 发现实例 ID
子系统(自动生成)federation对象 / {}联邦配置扩展位

扫描与音频分析参数除上表 config.json 中的 5 个外,还有 30+ 个运行时参数(扫描线程、波形、BPM、封面服务、discovery 模型等)由管理 API 管理(完整清单见 3.3 的 GET /api/v1/admin/db/params 实测回显),这些参数同样持久化到 config.json 或数据库,重启不丢。

五、核心参数分类详解

5.1 服务基础:port 与 secret

port 只决定进程内监听端口;服务化部署时对外端口在部署层映射(如 8155→3000),直接改 port 需同步调整端口映射。secret 是 JWT 签名密钥——更换它会让全部已签发 token 立即失效(所有用户需重新登录),适合在怀疑泄露时作为应急手段;默认值由首启随机生成,生产环境务必确认非默认弱值。

5.2 曲库扫描:scanOptions 五键协同

五个键共同决定「扫得多快、扫得多狠」:bootScanDelay: 5 让服务先完成启动再延迟 5 秒扫描,避免拖慢可用时间;pause: 50 在机械盘上能显著压平 IO 尖峰;saveInterval: 250 控制事务提交频率,超大曲库(数万轨)可调大减少写放大;scanInterval: 1.5(默认,小时)做定时增量,配合管理 API 的 watcherEnabled(文件监视器,实测默认 false)实现近实时入库。

5.3 用户与口令:PBKDF2 参数与 salt 生成

v6.32.0 的口令校验逻辑是:对输入口令用该用户的 salt 做 PBKDF2-SHA512、15000 次迭代、取 32 字节、base64 编码,与 password 存储值比对。因此 config users 段的两个键都必须是「生成值」而非明文。为演示口令 q1w2e3r4 生成合规值的完整过程:

openssl rand -base64 16

实测输出:

k7iA5oyj/jAkEi3KVWYEZQ==
python3 -c "
import base64, hashlib
salt = 'k7iA5oyj/jAkEi3KVWYEZQ=='
dk = hashlib.pbkdf2_hmac('sha512', b'q1w2e3r4', salt.encode(), 15000, 32)
print(base64.b64encode(dk).decode())
"

实测输出:

kRwJgrHolLWXdZp4fXOepkx9ODFTsddjYrOeO1uWNlY=

校验闭环:把这对值预置进 config("admin": true 赋予管理员位),重启后登录并确认权限位:

curl -s -X POST http://localhost:8155/api/v1/auth/login -H 'Content-Type: application/json' -d '{"username":"admin","password":"q1w2e3r4"}' -o /dev/null -w 'login -> %{http_code}\n'

实测输出:

login -> 200
curl -s -H "x-access-token: $TOKEN" http://localhost:8155/api/v1/admin/users

实测输出:

{"admin":{"admin":true,"vpaths":["music"],"allowMkdir":true,"allowUpload":true,"allowFileModify":true,"allowServerAudio":false,"allowTorrent":false,"allowDiscoveryJobs":false}}

allowMkdir/allowUpload/allowFileModify/allowServerAudio/allowTorrent/allowDiscoveryJobs 六个权限位控制普通用户能力边界,默认按安全侧收敛(torrent/discovery 关闭)。

5.4 users 段的生命周期:一次性迁移源

config 的 users 段只在「SQLite 中尚无该用户」的首启场景被迁移入库(实测日志:Starting migration from LokiJS/config to SQLite... → Migrated user: admin),迁移完成写入标记文件 db/.migrated-from-loki。两个实测结论:

  1. 迁移后修改 config users 段不会同步到已存在的数据库账号(账号管理走 Web 管理面板或 admin API);
  2. 重建数据库想重跑迁移时,必须连隐藏标记文件一起删除(rm -rf /srv/mstream/config/db 整目录删),否则迁移被跳过、登录报 user not found——这是实测踩过的坑。

5.5 子系统自动生成键

iroh/dlna/discovery/federation 四组键由首启自动生成,各自独立:iroh.secretKey 泄露等于 P2P 节点身份被冒用,按敏感值对待(生产环境不要把它提交进版本库);dlna.uuid 决定局域网 DLNA 设备身份,重建后客户端需重新发现;discovery.mdns.instanceId 是 mDNS 广播实例标识。

六、启动参数详解(CLI 参数矩阵)

除 config.json 外,mstream 可执行程序还有一组启动参数,--help 实测全量如下:

mstream --help

实测输出(完整照抄):

Usage: mstream [options]

Options:
  -V, --version        output the version number
  -j, --json <json>    Specify JSON Boot File (default: /app/mstream/save/conf/default.json)
  --portable           standalone binaries only: keep config + data next to
                       the binary (save/conf/...) instead of the per-user data
                       directory. An install that already has a config next to
                       the binary stays portable automatically.
  --quick-connect-off-by-default
                       standalone binaries only: when creating the first-run
                       config, leave Quick Connect (remote access) disabled.
                       Only shapes that generated default - an existing
                       config, including one where you enabled Quick Connect
                       yourself, is never changed.
  --supervised         exit when the launching process closes stdin (for
                       supervisors that run mStream as a managed child and
                       hold its stdin pipe open)
  --boot-probe         check that this build would boot with this machine's
                       config and database, print a "boot-probe:" line, and
                       exit 0/1 without starting anything (the installers
                       run this before switching an install to a new
                       version)
  -h, --help           display help for command

逐项说明与实测验证:

参数作用实测结果
-V, --version输出版本号输出 6.32.0,退出码 0
-j, --json <文件>指定启动配置文件(Boot File)路径默认路径随安装形态变化,服务化部署常配为自定义 config.json
--portable单二进制形态下把配置与数据放在二进制旁边适合 U 盘/免安装目录分发场景
--quick-connect-off-by-default首启配置默认关闭远程快速连接只影响首启生成的默认值,不改已有配置
--supervised父进程关闭 stdin 时随之退出供 systemd/supervisor 托管子进程时避免孤儿进程
--boot-probe校验当前构建能否用本机配置与数据库启动,打印 boot-probe 行后退出实测输出 boot-probe: ok (module graph),退出码 0;升级前自检用
-h, --help帮助如上完整回显

传错参数的行为也有明确语义:

mstream --port 9999

实测输出:

error: unknown option '--port'

退出码为 1。注意 v6.32.0 已无 --port/--user/--db 等旧式参数——端口、用户、库路径全部收敛到 config.json 与管理 API,脚本化部署用 -j 指定配置文件即可。

七、生产配置模板

适用场景:4 GB 内存、机械盘或 SATA SSD、曲库 1–5 万轨、家庭/小团队多用户。以下模板可直接替换生产值后使用(口令哈希用 5.3 的方法重新生成):

{
  "port": 3000,
  "secret": "<openssl rand -base64 32 生成的随机值>",
  "writeLogs": true,
  "noUpload": false,
  "scanOptions": {
    "skipImg": false,
    "scanInterval": 6,
    "pause": 100,
    "saveInterval": 500,
    "bootScanDelay": 10
  },
  "storage": {
    "albumArtDirectory": "/config/album-art",
    "dbDirectory": "/config/db",
    "logsDirectory": "/config/logs",
    "waveformCacheDirectory": "/config/waveform-cache"
  },
  "folders": {
    "music": { "root": "/music", "type": "music", "followSymlinks": false }
  },
  "users": {
    "admin": {
      "password": "<PBKDF2-SHA512 哈希>",
      "salt": "<openssl rand -base64 16 生成的盐值>",
      "admin": true,
      "vpaths": ["music"]
    }
  }
}

逐项解读:scanInterval 调到 6 小时降低大曲库空转;pause: 100 面向机械盘压平 IO;saveInterval: 500 减少事务次数;bootScanDelay: 10 避免与宿主其他服务抢占启动期资源;secret 必须换随机强值;followSymlinks 默认关,除非明确需要把多处目录链进曲库。模板不写子系统键(iroh/dlna/discovery/federation/setupComplete),它们由首启自动补齐。

八、常见问题(FAQ)

Q1:启动失败,日志循环报 ValidationError: "users.admin.salt" is required? 原因:config users 段每个用户必须携带 salt 键(16 字节 base64),缺失即校验失败。实测报错照抄:

2026-10-29T13:49:22.423Z error: Failed to validate config file
ValidationError: "users.admin.salt" is required

解决:openssl rand -base64 16 生成盐值补齐,重启后实测恢复(GET /login/ 回 200)。

Q2:登录报 Authentication Error: Passwords do not match? 原因与解决见 5.3:password 必须是 PBKDF2 哈希值而非明文;若错误值已入库,删 db 目录(含隐藏标记)重启重跑迁移。

Q3:重建数据库后 config 里的用户没迁移进去? 检查标记文件 db/.migrated-from-loki 是否残留——rm -rf db/* 不会删除隐藏文件。实测整目录删除 db 后重启,迁移日志重新出现且登录 200。

Q4:运行时改了扫描参数,重启后会丢吗? 不会。管理 API(3.3)修改的参数会写回 config.json(实测 scanInterval 由 API 改后文件中回显新值)。直接编辑 config.json 的改动需要重启进程生效,两者最终持久化形态一致。

Q5:mstream --boot-probe 失败说明什么? 退出码 1 且打印失败原因,表示当前配置或数据库无法随新版本启动,升级脚本应中止切换。本环境实测通过:boot-probe: ok (module graph)。

九、参考链接

  1. mStream 官方仓库(源码内 docs/json_config.md 为配置权威说明):https://github.com/IrosTheBeggar/mStream
  2. 站内延伸:《mStream 6.32.0 介绍与选型指南》、《mStream 6.32.0 Docker Compose 部署指南》、《mStream 6.32.0 API 使用详解》