使用docker-compose run挂载CIFS报权限拒绝,但exec可正常执行
docker-compose run挂载CIFS共享失败的问题 首先要明确一个核心差异:docker-compose run会创建一个全新的临时容器执行指定命令,而docker-compose up -d + exec是在完全遵循你docker-compose.yml配置的已启动容器内执行操作。两者的行为差异正是导致权限错误的关键,下面是具体的排查和解决方向:
1. 强制传递必要的内核权限
你的docker-compose.yml里配置了cap_add: - SYS_ADMIN - DAC_READ_SEARCH,这是挂载CIFS共享必须的内核权限。但你使用的docker-compose 1.20.1属于较旧版本,存在run命令无法自动继承服务配置中cap_add参数的已知问题。
解决尝试:
直接在run命令里显式添加权限:
docker-compose run --cap-add SYS_ADMIN --cap-add DAC_READ_SEARCH www ./myscript
2. 确认环境变量是否正确传递
虽然你在配置里声明了从宿主环境导入SAMBA_USER等变量,但docker-compose run在部分场景下可能无法正确读取这些宿主变量(比如执行run时宿主环境变量未被正确加载)。
验证&修复:
先在myscript开头加一行打印命令,确认变量值:
#!/bin/bash echo "SAMBA_USER: $SAMBA_USER, SAMBA_PATH: $SAMBA_PATH" mkdir -p /mnt/data mount -t cifs -o username=$SAMBA_USER,password=$SAMBA_PASS "$SAMBA_PATH" /mnt/data ls /mnt/data
如果输出为空,说明环境变量未传递,可在run命令中显式指定:
docker-compose run -e SAMBA_USER=$SAMBA_USER -e SAMBA_PASS=$SAMBA_PASS -e SAMBA_PATH=$SAMBA_PATH www ./myscript
3. 关闭SELinux标签限制(若宿主启用SELinux)
如果你的宿主机启用了SELinux,docker-compose run创建的临时容器可能会受到更严格的标签限制,导致挂载失败。
解决尝试:
在run命令中添加安全选项关闭SELinux标签:
docker-compose run --security-opt label=disable www ./myscript
4. 明确指定CIFS协议版本
部分Samba服务器需要明确指定CIFS协议版本才能正常挂载,虽然exec时能成功,但临时容器的挂载参数可能需要更明确的配置。
修改脚本:
在mount命令中添加vers参数(根据你的Samba服务器版本调整,比如vers=3.0或vers=1.0):
mount -t cifs -o username=$SAMBA_USER,password=$SAMBA_PASS,vers=3.0 "$SAMBA_PATH" /mnt/data
5. 确认容器运行身份
挂载操作需要root权限,确保docker-compose run启动的容器是以root身份运行的。你可以在脚本中添加whoami命令确认,或者在run命令中显式指定用户:
docker-compose run --user root www ./myscript
内容的提问来源于stack exchange,提问作者Luke Rohde

