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=supersecurepasswordfile_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共享时可正常运行
排查建议与解决方案
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"
- 主机挂载修改fstab:
验证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参数。TrueNAS SMB配置优化:
- 在TrueNAS的SMB共享设置中开启“允许更改权限”选项
- 优先使用SMB 3.1.1协议版本
- 确认数据集“共享类型”设置为“SMB”,权限继承配置正确
容器内部权限校验:
- 进入容器检查
/config目录权限与所有者:docker exec -it babybuddy bash ls -ld /config - 确保容器运行进程的UID/GID与
PUID/PGID一致,避免权限异常
- 进入容器检查
替代方案:若
nobrl无效,可将SQLite数据库放在容器本地存储,仅挂载静态文件到SMB;或改用支持网络锁的数据库(如PostgreSQL)。
内容的提问来源于stack exchange,提问作者spatak
相关产品推荐
相关产品推荐

