Docker Compose挂载CIFS卷部署报错及数据不写入问题排查
问题根因说明
最开始部署报错的核心原因是Docker命名卷不支持卷名后直接拼接子路径,你写的storagebox-share/simpletorrent/torrent-downloads会被Docker识别为一个全新的独立命名卷,和你顶层声明的storagebox-share卷完全无关,自然会报卷未声明的错误。
后续改相对路径后数据不落地,是两个问题叠加:
- 你同时配置了宿主机fstab挂载CIFS、Docker卷直连CIFS两套逻辑,链路重复容易出冲突
- Docker Compose里的相对路径卷默认会解析为当前部署项目工作目录下的本地绑定卷,数据直接写到宿主机Docker工作目录,根本没走到CIFS存储,自然在挂载盘里看不到文件。
排查与修复步骤
方案一:直接复用已有的fstab宿主机挂载(最稳定,推荐)
既然已经配好了宿主机层面的CIFS自动挂载,完全没必要让Docker再单独连一次CIFS创建卷,少一层链路少一堆兼容问题。
- 先修改fstab配置补全Hetzner存储盒需要的兼容参数,避免隐性读写失败:
//u[REDACTED].your-storagebox.de/backup /mnt/sbox1 cifs iocharset=utf8,rw,credentials=/etc/backup-credentials.txt,x-systemd.automount,x-systemd.requires=network-online.target,uid=0,gid=0,file_mode=0777,dir_mode=0777,vers=3.0,noperm,sec=ntlmssp 0 0
补的参数作用:
vers=3.0:强制使用SMB3.0协议,规避Hetzner存储盒对低版本SMB的兼容问题noperm:跳过CIFS客户端侧权限校验,避免Docker进程权限判定和存储盒服务端权限不一致导致写入失败sec=ntlmssp:指定认证方式,避免默认认证协商失败导致的假挂载x-systemd.requires=network-online.target:保证网络就绪后再执行挂载,避免开机挂载失败
- 执行命令重新加载fstab配置,验证宿主机挂载正常:
# 重新加载fstab mount -a # 确认挂载生效 mount | grep sbox1 # 提前创建需要的子目录和空配置文件,避免Docker自动创建时搞乱权限 mkdir -p /mnt/sbox1/simpletorrent/torrent-downloads touch /mnt/sbox1/simpletorrent/cloud-torrent.yaml chmod 777 /mnt/sbox1/simpletorrent -R # 手动写入测试文件,去Hetzner后台确认文件存在,证明宿主机读写正常 echo "test" > /mnt/sbox1/test.txt
- 修改Portainer Stack配置,删掉冗余的Docker命名卷定义,直接用宿主机绝对路径绑定挂载:
version: '3' services: service.simpletorrent: image: boypt/cloud-torrent restart: unless-stopped ports: - "3002:3000" environment: AUTH: "[REDACTED]:[REDACTED]" TITLE: "MySimpleTorrent" volumes: - /mnt/sbox1/simpletorrent/torrent-downloads:/srv/downloads - /mnt/sbox1/simpletorrent/cloud-torrent.yaml:/etc/cloud-torrent.yaml command: ["-c", "/etc/cloud-torrent.yaml"]
- 启动容器后执行校验,确认挂载生效:
# 查容器ID docker ps | grep simpletorrent # 进容器内部 docker exec -it <替换为实际容器ID> sh # 在容器内的挂载目录写测试文件 touch /srv/downloads/container_test.txt
回到宿主机查看/mnt/sbox1/simpletorrent/torrent-downloads目录,如果能看到container_test.txt,证明挂载完全正常。如果看不到,执行docker inspect <容器ID> | grep -A 10 Mounts查看实际挂载的源路径,确认路径配置没有写错。
方案二:使用Docker原生CIFS命名卷(不想用fstab时选这个)
如果要让Docker直接管理CIFS卷,不能在卷名后面直接拼子路径,必须用subpath参数指定卷内目录,同时也要加全CIFS兼容参数:
- 提前在Hetzner存储盒里创建好
simpletorrent/torrent-downloads目录,以及空的cloud-torrent.yaml文件,否则挂载时会因为子路径不存在直接报错。 - 使用如下Stack配置部署:
version: '3' services: service.simpletorrent: image: boypt/cloud-torrent restart: unless-stopped ports: - "3002:3000" environment: AUTH: "[REDACTED]:[REDACTED]" TITLE: "MySimpleTorrent" volumes: - type: volume source: storagebox-share target: /srv/downloads volume: subpath: simpletorrent/torrent-downloads - type: volume source: storagebox-share target: /etc/cloud-torrent.yaml volume: subpath: simpletorrent/cloud-torrent.yaml command: ["-c", "/etc/cloud-torrent.yaml"] volumes: storagebox-share: driver_opts: type: cifs o: "username=u[REDACTED],password=[REDACTED],addr=u[REDACTED].your-storagebox.de,vers=3.0,noperm,sec=ntlmssp,iocharset=utf8,rw,file_mode=0777,dir_mode=0777" device: "//u[REDACTED].your-storagebox.de/backup"
内容的提问来源于stack exchange,提问作者Stelios Papamichail
相关产品推荐
相关产品推荐

