xiaomusic 修改默认 8090 端口指南:docker-compose 端口映射失效问题排查与正确配置
【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic
导读
使用小爱音箱播放音乐的开源项目 xiaomusic 默认在 8090 端口提供服务,很多用户在 Docker 部署时习惯将容器端口映射为宿主机其他端口(如80:8090),却发现播放失败——日志里依然请求http://IP:8090而非映射后的地址。本文以 docs/issues/19.md 的实战问题为骨架,结合 config.py、music_library.py、README.md 等源码与文档,讲清楚port与public_port两个端口参数的真实含义、播放 URL 的生成链路,并给出 docker-compose、Docker CLI、反向代理、后台设置四种改端口方案,读完即可正确配置任意端口的 xiaomusic。
问题现象:映射端口后播放失败,日志仍调用 8090
Issue #19 描述的典型场景是:用户在 docker-compose 中把容器端口映射为宿主机 80 端口:
ports: - 80:8090结果播放失败,从日志可以看到程序依旧拼接出http://10.0.0.4:8090/...这样的播放地址,而不是映射后的 80 端口。日志中关键的一行是:
xiaomusic | [02/21/24 15:29:29] INFO 播放 xiaomusic.py:461 xiaomusic | http://10.0.0.4:8090/music/%E5%AE% xiaomusic | 89%E6%B2%B3%E6%A1%A5%E5%8C%97.mp3把映射还原成8090:8090后一切恢复正常。
这个现象的根本原因并不在 Docker,而在于xiaomusic 生成音乐播放 URL 时使用的端口不来自 Docker 映射规则,而是来自自身配置中的端口参数。只改 Docker 的ports映射,而应用内部仍认为自己在 8090 端口,就会生成无法访问的播放地址,小爱音箱自然拿不到音频流。
端口参数拆解:port 与 public_port 各管什么
xiaomusic 有两个与端口相关的配置项,定义在 config.py:
port: int = int(os.getenv("XIAOMUSIC_PORT", "8090")) # 监听端口 public_port: int = int(os.getenv("XIAOMUSIC_PUBLIC_PORT", 58090)) # 歌曲访问端口两者作用完全不同:
| 配置项 | 环境变量 | 默认值 | 作用 |
|---|---|---|---|
port | XIAOMUSIC_PORT | 8090 | 服务监听端口,即 HTTP 服务实际绑定的端口,也是xiaomusic进程监听的端口 |
public_port | XIAOMUSIC_PUBLIC_PORT | 58090 | 对外公布的歌曲访问端口,拼接在播放 URL 中;0表示与监听端口一致 |
对应的config-example.json中也保留着这两项默认值(见 config-example.json):
{ "port": 8090, "public_port": 58090 }后台设置页面(static/tailwind/setting.html)中同样有这两个字段,其中public_port被标注为"外网访问端口(0表示跟监听端口一致)"。
需要特别说明:当前仓库的默认public_port已是 58090,这是与 Issue #19 讨论时期(默认 8090)不同的新默认值,说明项目已经针对"歌曲访问端口必须独立配置"做了调整。但从源码逻辑上看,只要修改了port而不同步修改public_port,仍可能出现播放 URL 端口不一致的问题,因此下面的配置原则依然适用。
播放 URL 是如何拼出来的:源码调用链
之所以只改 Docker 映射无效,是因为播放 URL 完全由配置拼接生成,与 Docker 无关。核心逻辑在 music_library.py 的_get_file_url:
# 构造URL encoded_name = urllib.parse.quote(filename) url = f"{self.config.hostname}:{self.config.public_port}/music/{encoded_name}" return try_add_access_control_param(self.config, url)URL 由三部分组成:
hostname:默认http://192.168.2.5(见 config.py),通常改成局域网内 NAS/主机的 IP;public_port:歌曲访问端口,这是播放地址里真正出现的端口号;- 路径:
/music/歌曲名,如果歌曲在music_path子目录下则会带上子目录。
类似的拼接还出现在封面图 URL(music_library.py)和在线音乐代理 URL(music_library.py)中,全部使用hostname:public_port组合。也就是说,public_port是贯穿所有对外资源地址的关键参数。
而服务实际监听端口则来自port配置,在 cli.py 中读取:
port = int(config.port)因此整个链路可以概括为:
- HTTP 服务监听
port(默认 8090); - 播放时用
hostname + public_port拼出对外可访问的 URL; - 小爱音箱去访问这个 URL 拉取音频流;
- 如果
public_port对应的端口上根本没有服务(例如只改了 Docker 映射、没改配置),请求就会失败。
正确改端口的方案:三个数字必须一致
Issue #19 中维护者 hanxi 给出的结论非常明确:如果换端口,需要三个数字一致。即environment中的XIAOMUSIC_PORT、ports的宿主机端口与容器端口保持一致:
environment: XIAOMUSIC_PORT: 6874 ports: - 6874:6874这样服务监听6874,播放 URL 也拼出6874,Docker 又把6874原样暴露,全链路端口一致,播放自然正常。评论区补充的说明也印证了这一点:XIAOMUSIC_PORT可以按需设置,但要求上下两处端口都设置成同一个值,例如:
environment: XIAOMUSIC_PORT: 5678 ports: - 5678:5678更完整的解释(Issue #19 评论 5)把 docker-compose 中两者的对应关系归纳为:
ports: - aaaa:bbbb environment: XIAOMUSIC_PORT: bbbb # 对应配置中的 port,监听端口(修改后需要重启) XIAOMUSIC_PUBLIC_PORT: aaaa # 对应配置中的 public_port,外网访问端口(0 表示跟监听端口一致)结论是:Docker 环境中一般不需要修改 bbbb(容器内监听端口),也就是不必设置XIAOMUSIC_PORT。如果只是想换一个对外访问的端口,只需要把两处 aaaa 改成同一数字,并同步设置XIAOMUSIC_PUBLIC_PORT。
实战配置示例
方案一:docker-compose 换端口(监听端口不变)
保持容器内 8090 不变,只把对外暴露端口改成 5678,同时把public_port指到 5678:
services: xiaomusic: image: hanxi/xiaomusic container_name: xiaomusic restart: always environment: XIAOMUSIC_HOSTNAME: http://192.168.2.5 # 改成宿主机局域网 IP XIAOMUSIC_PUBLIC_PORT: "5678" # 对外访问端口 ports: - 5678:8090 volumes: - /xiaomusic_music:/app/music - /xiaomusic_conf:/app/conf后台访问地址为http://NAS_IP:5678。
方案二:docker-compose 连监听端口一起换
按 Issue #19 的"三数一致"原则,把监听端口、映射端口、public_port 全部设为同一值:
services: xiaomusic: image: hanxi/xiaomusic environment: XIAOMUSIC_PORT: 6874 # 监听端口 XIAOMUSIC_PUBLIC_PORT: 6874 # 歌曲访问端口 ports: - 6874:6874方案三:Docker CLI 运行
Docker CLI 与 compose 等价,注意环境变量与-p映射的配合:
docker run -p 5678:8090 \ -e XIAOMUSIC_HOSTNAME=http://192.168.2.5 \ -e XIAOMUSIC_PUBLIC_PORT=5678 \ -v /xiaomusic_music:/app/music \ -v /xiaomusic_conf:/app/conf \ hanxi/xiaomusicREADME 中也明确提醒(README.md):58090是 NAS 本地端口,8090是容器端口,不要去修改容器端口,后台访问地址为http://NAS_IP:58090。这与"Docker 环境中不需要修改XIAOMUSIC_PORT"的结论一致。
方案四:反向代理场景
如果使用 Nginx 等反向代理转发localhost:aaaa(即宿主机的对外映射端口),则XIAOMUSIC_PUBLIC_PORT应设置成代理的监听端口:
environment: XIAOMUSIC_PUBLIC_PORT: "8080" # 反向代理监听端口 ports: - 5678:8090server { listen 8080; server_name music.example.com; location / { proxy_pass http://127.0.0.1:5678; } }这样播放 URL 会生成http://hostname:8080/music/...,流量经反向代理转发到实际服务,既隐藏了内部端口,也解决了播放地址端口不一致的问题。
非 Docker 环境(pip / 开发模式)改端口
通过 pip 安装或源码运行时,同样遵循"监听端口"与"播放地址端口"两套逻辑:
# 查看帮助 xiaomusic --help # 使用配置文件启动(config.json 参考 config-example.json) xiaomusic --config config.json # 默认监听 8090 直接启动 xiaomusic默认监听端口 8090,后台 API 文档地址为http://localhost:8090/docs(见 README.md)。如果要把监听端口改成 8080,并让播放 URL 也指向 8080,需要同时设置XIAOMUSIC_PORT与XIAOMUSIC_PUBLIC_PORT:
export XIAOMUSIC_PORT=8080 export XIAOMUSIC_PUBLIC_PORT=8080 xiaomusic或者写入config.json:
{ "hostname": "http://192.168.2.5", "port": 8080, "public_port": 8080 }开发模式下(pdm run xiaomusic.py)默认监听端口同样是 8090,修改端口后记得重启服务使其生效。
避坑提醒:settings.json 会覆盖环境变量
Issue #19 评论 5 特别强调了一个关键点:setting 文件存在时会覆盖环境变量。xiaomusic 启动时会把配置文件中的设置读取并覆盖已有配置,相关逻辑在 xiaomusic.py:
# 尝试从设置里加载配置 config_data = self.config_manager.try_init_setting() if config_data: self.update_config_from_setting(config_data)配置文件的路径由conf_path决定,默认为conf/setting.json(见 config.py 的getsettingfile方法)。也就是说:
- 如果
conf/setting.json中已经写入过旧的端口值,即使你改了环境变量或 docker-compose,启动时也会被文件中的旧值覆盖; - 启动过之后修改端口,应该直接修改
settings.json,或者在后台"设置"页面修改后保存,而不是只改环境变量; - 在后台修改配置会通过 api/routers/system.py 的
/api/system/modifiysetting接口更新配置并落盘,涉及port、hostname等 HTTP 服务器相关配置时还会触发reset_http_server重置 HTTP 服务。
因此排查"改了端口不生效"问题时,第一件事就是检查conf/setting.json里是否残留了旧端口。
小结
| 排查/配置项 | 结论 |
|---|---|
只改 Dockerports映射 | 无效,播放 URL 由应用配置生成,与映射无关 |
port/XIAOMUSIC_PORT | 服务监听端口,修改后需要重启 |
public_port/XIAOMUSIC_PUBLIC_PORT | 播放 URL 中出现的对外端口,0表示与监听端口一致 |
| Docker 最佳实践 | 不改容器内端口,只改对外映射端口 + 同步XIAOMUSIC_PUBLIC_PORT |
| 反向代理 | XIAOMUSIC_PUBLIC_PORT设为代理监听端口,代理转发到实际端口 |
| 配置优先级 | conf/setting.json覆盖环境变量,改端口后需同步修改或后台保存 |
| 最终验证 | 查看日志中播放 http://IP:PORT/music/...一行的端口是否可访问 |
修改 xiaomusic 端口时牢记两个原则:一,播放地址端口来自public_port,而不是 Docker 映射;二,配置文件会覆盖环境变量。把握住这两点,无论 Docker、反向代理还是 pip 部署,都能让端口修改一次到位。
【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考