侧边栏壁纸
博主头像
Big Qiang

行动起来,活在当下

  • 累计撰写 16 篇文章
  • 累计创建 2 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

把全网音乐搬进群晖:go-music-dl 部署实录

go-music-dl.png

目标:用 Container Manager 跑起 go-music-dl,网页里搜歌、点下载,文件直接落进 /volume1/Music,Audio Station 立刻能播。

全文只需要一个 compose 文件、一次账号初始化、一次路径设置。


一、为什么用容器

go-music-dl 有三种形态:

形态 平台 适合 NAS 吗
桌面客户端 Windows / macOS 不适合,是 WebView 壳程序
Web 服务 全平台 可以,单文件二进制
容器镜像 amd64 / arm64 推荐,内置 ffmpeg

镜像里已经打包了 ffmpeg,所以「内嵌封面、写入歌词」这类需要转码的功能开箱可用,不用在 NAS 上另外装。


二、动手前确认三件事

SSH 登录 NAS(控制面板 → 终端机 → 启用 SSH):

uname -m            # x86_64 → amd64;aarch64 → arm64
cat /etc/VERSION    # DSM 7.2+ 用 Container Manager,7.1/6.x 用 Docker 套件
id 你的账号

id 的输出类似:

uid=1026(你的账号) gid=100(users) groups=100(users),101(administrators)

记下 uid 和 administrators 的组号,等会儿要用。群晖上管理员账号的 uid 通常是 1026,administrators 组固定是 101。

低端 ARM 机型(DS120j、DS220j 等 Marvell 芯片)没有 Docker 支持,只能走二进制 + 计划任务的方式,功能一样但升级要手动。


三、准备目录

两个目录,分开存放:

/volume1/docker/music-dl/data     ← 数据库、Cookie、自建歌单(备份只拷这个)
/volume1/Music                    ← 音乐库,也是 Audio Station 的索引目录
sudo mkdir -p /volume1/docker/music-dl/data

四、docker-compose

Container Manager → 项目 → 新增 → 创建 docker-compose.yml,路径填 /volume1/docker/music-dl,内容:

services:
  music-dl:
    image: guohuiyuan/go-music-dl:latest
    container_name: music-dl
    restart: unless-stopped
    ports:
      - "8088:8080"
    user: "1026:101"
    entrypoint: ["/bin/sh", "-c"]
    command: ["exec ./music-dl web --port 8080 --no-browser"]
    volumes:
      - /volume1/docker/music-dl/data:/home/appuser/data
      - /volume1/Music:/music
      - /volume1/Music:/home/appuser/data/downloads
    environment:
      - TZ=Asia/Shanghai

几个关键点:

user: "1026:101" —— 把 1026 换成你上一步 id 里的 uid,101 是 administrators 组(一般不用改)。镜像默认以 UID 1000 运行,而群晖共享文件夹的权限体系里往往找不到 1000 这个用户,容易写不进去。直接用你的管理员账号身份跑,最省事,生成的文件你在 File Station 里也能直接改。

entrypoint 和 command —— 镜像默认入口会先切到 UID 1000 再启动程序。既然上面已经指定了身份,就必须绕过这一步,否则启动即失败。这两行照抄即可。

三条挂载:

宿主机 容器内 用途
/volume1/docker/music-dl/data /home/appuser/data 数据库、Cookie、歌单
/volume1/Music /music 音乐库,供设置里填 /music
/volume1/Music /home/appuser/data/downloads 程序的默认下载目录,直连音乐库

第三条是省事的关键:程序默认下载目录固定是 data/downloads,把它挂到音乐库上,等于「什么都不填也能下到 /volume1/Music」。

data/downloads 是 data 的子目录,Docker 支持这种嵌套挂载,子挂载覆盖父目录中的同名文件夹,数据库本身不受影响。

如果拉镜像卡住,去 注册表 → 设置 加加速地址,或把 image 改成 docker.m.daocloud.io/guohuiyuan/go-music-dl:latest。


五、启动与初始化

sudo docker logs --tail 20 music-dl

看到这两行就成功:

Web setup token: 一串随机字符
Web started at http://localhost:8080/music

浏览器打开 http://群晖IP:8088/music/setup,填日志里的 token,设置用户名和密码(至少 6 位)。

几点说明:

  • 这个账号是应用自己的,跟 DSM 登录账号无关
  • token 只在「还没创建管理员」时打印,每次重启都会换新的,旧的立即作废。忘了取就 sudo docker logs music-dl | grep "setup token"
  • 已经初始化过就不会再有这行,直接访问 /music 登录即可
  • 忘记密码没有找回命令,只能停容器、移走 data/settings.db 重新初始化(会丢 Cookie 和自建歌单,已下载的歌不受影响)

六、下载目录怎么填(最容易错的一步)

登录后右上角齿轮 → 下载 标签 → 下载目录填:

/music

保存。

同一个文件夹的三个叫法

你看到的位置 路径
File Station / SSH 里 /volume1/Music
容器内部 /music
程序默认值 data/downloads

设置里要填容器内的路径,也就是 /music。填成 /volume1/Music 会失败,因为那是宿主机路径,容器里看不见(除非挂载点就叫这个名字)。

常见报错:mkdir /Music: permission denied

如果填成大写 /Music,Linux 区分大小写,容器里没有这个目录,程序会试图在根目录创建它——而容器以非 root 身份运行,建不了,于是报这个错。

改成小写 /music 即可。 顺便说明,容器内报出的任何「在根目录建文件夹被拒」都是同一个原因:路径写错了。

提示"当前浏览器无法获取服务器上的完整目录"

在网页版点「选择目录」会弹这句话,不是错误。

那个按钮只在桌面客户端里有效(WebView 会注入选择器)。浏览器只能看到你自己电脑的目录,看不到 NAS 的,所以程序退化成"请手动输入路径"。

直接在输入框填 /music 就行,不要点浏览按钮。右侧工具栏的「打开下载目录」按钮同理,它请求在服务器那台机器上打开文件夹,NAS 没有桌面环境,点了没反应是正常的。


七、验证

# 1. 身份对不对
sudo docker exec music-dl id

# 2. 三条挂载在不在
sudo docker inspect music-dl --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{"\n"}}{{end}}'

# 3. 能不能写
sudo docker exec music-dl sh -c "touch /music/.wtest && echo WRITE_OK; rm -f /music/.wtest"

三条都要符合预期,然后网页里搜一首歌点下载:

ls -l /volume1/Music | tail -5

文件出现、属主是你自己的账号、大小不为 0 —— 全链路通了。

最后 Audio Station → 设置 → 共享文件夹 添加 /volume1/Music 并重新索引,DS audio 里就能播放。


八、排错速查

现象 原因 处理
容器反复重启,日志 SQLite: unable to open database file: out of memory (14) 容器身份对 data 目录没有写权限(out of memory 是误导性文案,14 是"打不开文件") 确认 user: 的 uid 正确;仍不行就把 data 换成命名卷,见下
启动报 su-exec / operation not permitted 指定了 user: 但没覆盖 entrypoint 加上 entrypoint 和 command 两行
mkdir /Music: permission denied 大小写写错 改 /music
mkdir /volume1/...: permission denied 填了宿主机路径 改成容器内路径
下载失败但目录权限正常 平台直链被限流,报错文案误导 换音源重试,或去 Cookie 标签填对应平台
点按钮没反应 浏览器缓存了旧页面 Ctrl+Shift+R 强刷,用无痕窗口验证
进 /music/setup 提示 token 失效 每次重启都会重新生成 从日志取最新的 token

关于第一条:如果 data 目录所在的共享文件夹启用了 Windows ACL,chown 1000:1000 和 chmod 777 都可能无效(ACL 生效时会忽略 POSIX 模式位)。最省事的绕法是改用命名卷,权限由 Docker 托管:

    volumes:
      - music-dl-data:/home/appuser/data
volumes:
  music-dl-data:

数据会放在 /volume1/@docker/volumes/music-dl-data/_data,备份时从这里拷 settings.db。


九、日常维护

升级

项目 → 操作 → 拉取并重置。或命令行:

cd /volume1/docker/music-dl && sudo docker compose pull && sudo docker compose up -d

备份

只有 settings.db 有价值(账号、Cookie、歌单),音乐文件本身就在 Music 里:

sudo mkdir -p /volume1/docker/music-dl/backup
sudo tar -czf /volume1/docker/music-dl/backup/settings-$(date +%F).tar.gz \
  -C /volume1/docker/music-dl data

控制面板 → 任务计划 → 用户自定义脚本,设成每周执行。

外网访问

控制面板 → 登录门户 → 高级 → 反向代理:来源 HTTPS / music.你的域名 / 443,目标 localhost / 8088。不需要 WebSocket。证书用 DSM 自带的 Let's Encrypt。

Cookie

「Cookie」标签按平台填。不填也能搜能下,只是部分平台会限流或降音质;填错反而可能导致解析失败,建议真遇到"无版权 / 需登录"再补。Cookie 有效期有限,过期了需要重新粘。


附:配置速查

访问地址   http://群晖IP:8088/music/     (路径必须带 /music)
数据目录   /volume1/docker/music-dl/data
音乐目录   /volume1/Music                (容器内 /music)
端口       8088 → 容器 8080
services:
  music-dl:
    image: guohuiyuan/go-music-dl:latest
    container_name: music-dl
    restart: unless-stopped
    ports:
      - "8088:8080"
    user: "1026:101"
    entrypoint: ["/bin/sh", "-c"]
    command: ["exec ./music-dl web --port 8080 --no-browser"]
    volumes:
      - /volume1/docker/music-dl/data:/home/appuser/data
      - /volume1/Music:/music
      - /volume1/Music:/home/appuser/data/downloads
    environment:
      - TZ=Asia/Shanghai

复制前把 1026 换成你 id 命令里的 uid,101 一般是 administrators 组,不用动。


后记

容器部署在群晖上最常见的摩擦点只有一个:容器里以什么身份跑,和你那个文件夹放行了谁,这两件事要对齐。想清楚这一点,后面都是路径写法问题。

同一套思路可以直接搬到 qBittorrent、Navidrome、Immich 这类服务上——先 id 看一眼自己的 uid 和组,再决定 user: 填什么,能省掉大半权限调试时间。

目标:在群晖 NAS 上用 Container Manager 跑起 go-music-dl,下载的歌直接落进 /volume1/Music,Audio Station 立刻能播。

这篇不是"复制粘贴就能跑"的速通,而是把过程中踩到的三个坑连同根因一起写清楚。如果你在群晖上跑任何"容器内以非 root 用户写共享文件夹"的服务,这三个坑大概率会全部遇到。


一、这个项目是什么

go-music-dl 是一个聚合搜索 + 解析下载的工具:网页里搜歌,它去网易云、QQ、酷狗、汽水等平台找源,解析出音频直链并下载到本地,可带封面、歌词,还支持 WebDAV 同步和简单的播放器。

它有三种形态:

形态 平台 说明
桌面客户端 Windows / macOS Rust + WebView2 写的壳,不适合 NAS
Web 服务 全平台 单文件二进制,music-dl web 起一个网页
容器镜像 amd64 / arm64 推荐给 NAS,内置 ffmpeg

群晖上只能走容器(或二进制 + 计划任务),桌面版是 WebView 程序,跑不起来。


二、前置确认

SSH 登录 NAS(控制面板 → 终端机 → 启用 SSH),先确认三件事:

uname -m            # x86_64 → amd64;aarch64 → arm64
cat /etc/VERSION    # DSM 7.2+ 用 Container Manager;7.1/6.x 用 Docker 套件
id 你的管理员账号     # 记下 uid 和 administrators 的 gid,后面要用

输出长这样:

uid=1026(kang) gid=100(users) groups=100(users),101(administrators),1023(http)

记住两个数字:uid = 1026,administrators 组 = 101。这是后面绕开权限坑的钥匙。

低端 ARM 机型(DS120j、DS220j 这类 Marvell 芯片)没有 Docker 支持,只能走文末的二进制方案。


三、目录规划

只需要两个目录,别把数据库和音乐库塞在一起:

/volume1/docker/music-dl/data     ← settings.db、Cookie、自建歌单(备份只拷这个)
/volume1/Music                    ← 下载的音乐(建议就是 Audio Station 的索引目录)
sudo mkdir -p /volume1/docker/music-dl/data

四、docker-compose 全文

Container Manager → 项目 → 新增 → 创建 docker-compose.yml,路径填 /volume1/docker/music-dl,内容:

services:
  music-dl:
    image: guohuiyuan/go-music-dl:latest
    container_name: music-dl
    restart: unless-stopped
    ports:
      - "8088:8080"
    user: "1026:101"
    entrypoint: ["/bin/sh", "-c"]
    command: ["exec ./music-dl web --port 8080 --no-browser"]
    volumes:
      - /volume1/docker/music-dl/data:/home/appuser/data
      - /volume1/Music:/music
      - /volume1/Music:/home/appuser/data/downloads
    environment:
      - TZ=Asia/Shanghai

user、entrypoint、三条挂载,每一行都不是随手写的,下面逐条解释。


五、坑一:SQLite 报 "out of memory",其实是 ACL 挡住了

现象

容器无限重启,日志反复刷同一段 panic:

panic: Failed to connect to SQLite: unable to open database file: out of memory (14)
Failed to read web auth settings: unable to open database file: out of memory (14)

根因

(14) 是 SQLite 的错误码 SQLITE_CANTOPEN,意思是打不开数据库文件。"out of memory" 是纯 Go 驱动 modernc/glebarez 给的一句误导性错误信息,跟内存毫无关系。

数据库路径是 data/settings.db(相对 WORKDIR /home/appuser),也就是 /home/appuser/data/settings.db,来自挂载的 /volume1/docker/music-dl/data。镜像默认以 UID 1000 运行,于是问题变成:1000 能不能写这个目录。

怎么确认是 ACL

# 1. 用同 UID 的临时容器去写,等价于"容器内那个用户能不能写"
sudo docker run --rm -u 1000:1000 -v /volume1/docker/music-dl/data:/data alpine:3.22 \
  sh -c "touch /data/.wtest && echo WRITE_OK || echo WRITE_FAIL"

结果是 WRITE_FAIL。再看权限:

ls -ldn /volume1/docker/music-dl/data
# drwxrwxrwx+ 1 1000 1000 0 Nov 14 12:04 ...      ← 注意末尾那个 +

sudo synoacltool -get /volume1/docker/music-dl/data | head -6
# ACL version: 1
# [0] group:administrators:allow:rwxpdDaARWc--:fd--
# [1] user:ContainerManager:allow:rwxpdDaARWc--:fd--

关键就是那个 +:目录启用了 Windows ACL。ACL 里只有 administrators 和 ContainerManager 两条放行记录,没有任何给 UID 1000 的条目。

而在启用了 ACL 的群晖共享文件夹上,POSIX 的拥有者模式位会被忽略——所以你看到 rwxrwxrwx 也没用,chmod 777 不会生效,chown 1000:1000 也只是改了"拥有者"这一栏,并不会在 ACL 里加一条记录。

这就是最容易误判的地方:权限看起来全开,实际写不进去。

解法 A(本文采用):让容器以 ADMIN 身份运行

既然 ACL 放行的是 group:administrators,那就让容器进程带这个组:

user: "1026:101"

1026 = kang 的 uid,101 = administrators 的 gid。这样不用改任何 ACL、不碰任何共享文件夹权限,而且新生成的文件属主就是你自己的账号,SMB 里也能直接管理。

解法 B:数据目录改用 Docker 命名卷

命名卷在 /volume1/@docker/volumes/ 下,权限由 Docker 托管,完全绕开共享文件夹 ACL:

    volumes:
      - music-dl-data:/home/appuser/data
volumes:
  music-dl-data:

代价是备份时要去 /volume1/@docker/volumes/music-dl-data/_data 取文件,稍微绕。

本文选 A,因为下载目录 /volume1/Music 本身也是带 ACL 的共享文件夹,用 A 可以一次解决两处写入问题,不用分别处理。


六、坑二:以管理员身份运行,还要覆盖 entrypoint

设了 user: "1026:101" 之后,容器仍然启动失败,报 su-exec 相关的错。

原因是镜像的默认入口会执行 su-exec appuser ... 切到 UID 1000 再启动主程序。你已经用 user: 指定了 1026,进程不是 root,再 su-exec 到 1000 必然失败。

所以要把入口一起覆盖掉:

    entrypoint: ["/bin/sh", "-c"]
    command: ["exec ./music-dl web --port 8080 --no-browser"]

顺带一个好处:默认入口里还有一句 chown -R 把 data 目录整个递归改属主。绕过入口后这句不再执行,也就不会每次重启都把整个音乐库重新扫一遍改权限——库大了这点很致命。


七、坑三:下载目录有三层路径,填错就 permission denied

这是最容易反复踩的一个。同一个文件夹,在三个地方有三个叫法:

位置 路径
群晖宿主机(File Station / SSH) /volume1/Music
容器内(挂载点) /music
程序默认值(相对 WORKDIR) data/downloads

典型报错一

mkdir /Music: permission denied

填了 /Music——容器内挂载点是小写 /music,Linux 区分大小写,/Music 在容器根目录不存在。容器以 UID 1026 非 root 运行,无权在根目录建文件夹,于是 mkdir 直接 permission denied。

典型报错二

填了 /volume1/Music。这是宿主机路径,容器里看不到它(除非挂载点就叫这个名字),结果同上:尝试在容器根目录建 /volume1/...,失败。

怎么验证

sudo docker exec music-dl ls -ld /music
# drwxrwxrwx ... /music          ← 存在,这才是容器内的正确路径

sudo docker exec music-dl ls -ld /volume1/Music
# ls: /volume1/Music: No such file or directory

sudo docker exec music-dl sh -c "touch /music/.wtest && echo WRITE_OK; rm -f /music/.wtest"
# WRITE_OK

本文的双保险

除了 /volume1/Music:/music,还多挂了一条:

- /volume1/Music:/home/appuser/data/downloads

程序默认下载目录就是 data/downloads(源码 core/config_store.go 里 DefaultWebDownloadDir = "data/downloads"),这条挂载等于把默认值直接接到音乐库。也就是说:

  • 界面上填 /music → 落到 Music
  • 界面完全不填(默认 data/downloads)→ 还是落到 Music

data/downloads 是 data 的子目录,Docker 支持这种嵌套挂载,子挂载覆盖父挂载中的同名目录,数据库目录本身不受影响。

另外要注意:容器内以 1026 运行时,不要填 /volume1/Music,也不要填大写。想保持"看起来像宿主机路径"的话,把挂载写成 - /volume1/Music:/volume1/Music,容器内就会出现同名路径。


八、启动与初始化

sudo docker logs --tail 20 music-dl

看到这两行就成功了:

Web setup token: dbf2Zq3eQQAYTSflwvOjCtRm_AyPS2WT
Web started at http://localhost:8080/music
  • Web setup token 只在"还没创建管理员"时打印,每次重启都会换新的,旧的作废
  • 已经初始化过就不会再有这行,直接登录即可

浏览器打开 http://群晖IP:8088/music/setup,填 token + 用户名 + 密码(≥6 位)。这是应用自己的账号,跟 DSM 的 kang 无关。

忘了密码没有重置命令,只能停容器、移走 data/settings.db 重新初始化(会丢 Cookie 和自建歌单,已下载的歌不受影响)。


九、配置下载目录

登录后右上角齿轮 → 下载 标签 → 下载目录填:

/music

保存。

关于"当前浏览器无法获取服务器上的完整目录"

在网页版点"选择目录"会弹出这句提示,这不是错误:

源码里这个按钮只在桌面客户端可用(WebView 会注入 window.musicDlPickDownloadFolder)。浏览器只能看见你自己电脑的目录,看不见 NAS 上的目录,所以程序退化成"让你手填路径"。

正确做法:直接在输入框填 /music,不要点浏览按钮。

同理,右侧工具栏的「打开下载目录」按钮在网页版也没用,它请求的是"在服务器那台机器上打开文件夹",NAS 上没有桌面环境,点了没反应是正常的。


十、验证清单

# 1. 身份对不对
sudo docker exec music-dl id
# uid=1026(kang) gid=101(administrators)

# 2. 三条挂载在不在
sudo docker inspect music-dl --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{"\n"}}{{end}}'
# /volume1/docker/music-dl/data -> /home/appuser/data
# /volume1/Music -> /music
# /volume1/Music -> /home/appuser/data/downloads

# 3. 数据库落盘了没
ls -l /volume1/docker/music-dl/data
# settings.db,属主 kang

# 4. 能写不能写
sudo docker exec music-dl sh -c "touch /music/.wtest && echo WRITE_OK; rm -f /music/.wtest"

然后网页里搜一首歌点下载:

ls -l /volume1/Music | tail -5

出现文件、属主是 kang、大小不为 0 —— 全链路通了。

最后去 Audio Station → 设置 → 共享文件夹 把 /volume1/Music 加进索引,DS audio 里就能直接播。


十一、一个容易被当成 bug 的现象:点了按钮没反应

症状:登录后点右上角齿轮,什么也不发生;退出登录后点,倒是会跳登录页。

排查过程走了弯路,最后定位到浏览器缓存了旧页面。

为什么能确定是缓存

从源码看,齿轮按钮的处理函数第一句就是 modal.style.display = "flex",先弹窗再发请求,不存在"等接口返回才显示"。后面每一处 DOM 取值都有空判断,不会静默失败。所以只要函数被调用、且没收到 401,窗口就一定会出现。

能让它"完全没反应"的只剩一种:页面里根本没有 #cookieModal 这个节点 —— 也就是加载到的是旧版 HTML。

验证方法

用无痕窗口打开同一个地址(无痕默认不读缓存、禁用扩展),重新登录后点齿轮,正常。回普通窗口按 Ctrl+Shift+R 强制刷新即可。

顺带两个排查技巧

  1. 地址后面加 ?open_config=1,页面加载完成后会自动调用同一个函数打开设置,绕过按钮点击,能快速区分是"按钮问题"还是"会话问题"
  2. 控制台一行定位:
[typeof openSystemConfig, !!document.getElementById('cookieModal')].join(' | ')
// function | true   → 页面正常,问题在点击(或被别的元素挡住)
// function | false  → 页面是旧的,强刷

右侧那一列图标间距只有 6px(齿轮 / 定时停止 / 登录退出 / 打开下载目录),手机上很容易点偏到「打开下载目录」,而它在网页版毫无反应,症状和"设置打不开"一模一样。


十二、故障速查表

现象 根因 处理
SQLite: unable to open database file: out of memory (14) ACL 里没有该 UID 的条目,chmod/chown 无效 用 user: "uid:gid" 以 administrators 组运行,或改命名卷
su-exec / operation not permitted 覆盖了 user 但没覆盖 entrypoint 加 entrypoint: ["/bin/sh","-c"] + command: ["exec ./music-dl ..."]
mkdir /Music: permission denied 大小写错了,容器内是 /music 改成小写
mkdir /volume1/...: permission denied 填了宿主机路径 改成容器内路径,或把挂载点改成同名
下载报 permission denied,但目录权限正常 平台解析出的直链被限流,文案误导 换音源重试,或去 Cookie 标签填对应平台
点按钮无反应 浏览器缓存了旧页面 / 点偏到相邻图标 Ctrl+Shift+R,无痕窗口验证
进 /music/setup 提示 token 失效 每次重启都会换新 token `docker logs
拉镜像卡住 国内网络 注册表加加速地址,或镜像名前加 docker.m.daocloud.io/

十三、日常维护

升级

Container Manager → 项目 → 操作 → 拉取并重置。或者:

cd /volume1/docker/music-dl && sudo docker compose pull && sudo docker compose up -d

备份

只有 data/settings.db 有价值(账号、Cookie、歌单),音乐文件本身在 Music 里:

sudo mkdir -p /volume1/docker/music-dl/backup
sudo tar -czf /volume1/docker/music-dl/backup/settings-$(date +%F).tar.gz \
  -C /volume1/docker/music-dl data

控制面板 → 任务计划 → 用户自定义脚本,设成每周一次。

外网访问

控制面板 → 登录门户 → 高级 → 反向代理:来源 HTTPS / music.你的域名 / 443,目标 localhost / 8088。不需要 WebSocket。证书用 DSM 自带的 Let's Encrypt 即可。

「Cookie」标签按平台填。不填也能搜能下,只是部分平台会限流或降音质。填错反而会导致解析失败,建议等真遇到"无版权 / 需登录"再补。


附:最终配置速查

访问地址   http://群晖IP:8088/music/
容器身份   uid=1026(kang) gid=101(administrators)
数据目录   /volume1/docker/music-dl/data     (settings.db 在这里)
音乐目录   /volume1/Music                    (容器内 /music)
默认端口   8088 → 容器 8080
路由前缀   /music(地址必须带这个后缀)
services:
  music-dl:
    image: guohuiyuan/go-music-dl:latest
    container_name: music-dl
    restart: unless-stopped
    ports:
      - "8088:8080"
    user: "1026:101"
    entrypoint: ["/bin/sh", "-c"]
    command: ["exec ./music-dl web --port 8080 --no-browser"]
    volumes:
      - /volume1/docker/music-dl/data:/home/appuser/data
      - /volume1/Music:/music
      - /volume1/Music:/home/appuser/data/downloads
    environment:
      - TZ=Asia/Shanghai

后记

三个坑的共性其实是同一件事:群晖把 Linux 的权限模型又套了一层 ACL,而容器世界默认还是按 UID 思考。所以"容器里以什么身份跑"和"目标目录的 ACL 放行了谁",这两件事必须对齐一次,剩下的都是路径写法问题。

如果以后在群晖上部署别的容器(qBittorrent、Immich、Navidrome 之类),直接照搬 user: "uid:gid" 这个思路,能省掉一大半权限调试时间。

博主关闭了所有页面的评论