You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器访问TrueNAS SMB共享的权限与数据库锁问题排查

容器挂载SMB共享出现SQLite数据库锁问题排查求助

环境配置

  • 虚拟化平台:Proxmox,部署TrueNAS Scale NAS和运行Docker的Debian虚拟机
  • TrueNAS配置:创建SMB和NFS共享数据集(NFS用于问题排查)
  • SMB账号:steve(UID:1000,GID:1000),拥有完全控制权限,Windows和Debian CLI可正常读写
  • Debian主机:创建同UID/GID的steve用户,SMB挂载命令如下:
    //192.168.10.206/dockerdata /mnt/dockershare cifs uid=1000,gid=1000,vers=3.0,credentials=/root/.truenascreds 0 0
    
    凭证文件/root/.truenascreds内容:
    username=steve
    password=supersecurepassword
    
    添加file_mode=0777,dir_mode=0777,noexec,nosuid,nosetuids,nodev参数后,挂载目录仍可正常读写。

问题现象

启动容器后出现数据库锁错误,WebUI返回500错误,日志关键信息:

sqlite3.OperationalError: database is locked

django.db.utils.OperationalError: database is locked

django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table (database is locked)

已尝试的容器挂载方式

方式1:映射主机已挂载的SMB目录

Docker Compose配置:

version: "2.1"

services:
  babybuddytestsmbmount:
    image: lscr.io/linuxserver/babybuddy:latest
    container_name: babybuddytestsmbmount
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - CSRF_TRUSTED_ORIGINS=http://127.0.0.1:8000,https://babybuddy.domain.com
    ports:
      - 1801:8000
    restart: unless-stopped
    volumes:
      - /mnt/dockershare/babybuddy2:/config

方式2:Docker卷直接挂载SMB共享

Docker Compose配置:

version: "2.1"

services:
  babybuddy:
    image: lscr.io/linuxserver/babybuddy:latest
    container_name: babybuddy
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - CSRF_TRUSTED_ORIGINS=http://127.0.0.1:8000,https://babybuddy.domain.com
    ports:
      - 1800:8000
    restart: unless-stopped
    volumes:
      - dockerdata:/config

volumes:
  dockerdata:
    driver_opts:
      type: "cifs"
      o: "username=steve,password=supersecurepassword,uid=1000,gid=1000,file_mode=0777,dir_mode=0777,noexec,nosuid,nosetuids,nodev,vers=3.0"
      device: "//192.168.10.206/dockerdata"

也曾简化挂载选项为:

o: "username=steve,password=supersecurepassword,uid=1000,gid=1000,rw,vers=3.0"

两种方式均出现相同数据库锁错误。

其他尝试操作

  • 推测容器以root身份访问SMB被TrueNAS阻止,尝试修改文件所有者为root:root无效
  • 调整TrueNAS数据集权限无效
  • 更换Ubuntu作为Docker主机无效
  • 容器使用本地存储或NFS共享时可正常运行

排查建议与解决方案

  1. SMB协议锁机制兼容处理:SQLite依赖文件系统的flock()/fcntl()锁机制,SMB对字节范围锁的支持存在兼容性问题,建议添加*nobrl*(禁止字节范围锁)参数:

    • 主机挂载修改fstab:
      //192.168.10.206/dockerdata /mnt/dockershare cifs uid=1000,gid=1000,vers=3.0,credentials=/root/.truenascreds,nobrl 0 0
      
    • Docker卷挂载修改o参数:
      o: "username=steve,password=supersecurepassword,uid=1000,gid=1000,file_mode=0777,dir_mode=0777,nobrl,vers=3.0"
      
  2. 验证SMB文件锁支持:在Debian主机挂载的SMB目录下,测试文件锁是否正常:

    touch /mnt/dockershare/test.lock
    flock /mnt/dockershare/test.lock sleep 60 &
    # 新开终端执行
    flock /mnt/dockershare/test.lock echo "Lock acquired"
    

    若第二个命令立即执行而非等待60秒,说明SMB共享不支持文件锁,必须使用nobrl参数。

  3. TrueNAS SMB配置优化:

    • 在TrueNAS的SMB共享设置中开启“允许更改权限”选项
    • 优先使用SMB 3.1.1协议版本
    • 确认数据集“共享类型”设置为“SMB”,权限继承配置正确
  4. 容器内部权限校验:

    • 进入容器检查/config目录权限与所有者:
      docker exec -it babybuddy bash
      ls -ld /config
      
    • 确保容器运行进程的UID/GID与PUID/PGID一致,避免权限异常
  5. 替代方案:若nobrl无效,可将SQLite数据库放在容器本地存储,仅挂载静态文件到SMB;或改用支持网络锁的数据库(如PostgreSQL)。

内容的提问来源于stack exchange,提问作者spatak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:21