如何解决Docker容器内Python脚本向挂载卷写入文件的权限报错问题
问题根因
你遇到的权限报错主要来自三个层面:
- RHEL 7系统默认开启的SELinux安全策略,限制了Docker容器对挂载的宿主机目录的写入权限
- Dockerfile中创建了自定义用户但未指定容器以该用户运行,同时挂载操作覆盖了容器内预先设置的目录权限
- flask-session默认将会话数据写入/app/flask_session路径,该路径属于挂载的宿主机目录,权限继承宿主机规则导致容器内进程无写入权限
解决方案
方案1:修复SELinux权限(RHEL系统特有高频问题)
RHEL/CentOS系列系统的SELinux默认会阻止Docker容器读写挂载的宿主机目录,可按以下方式处理:
- 临时验证:在宿主机执行
sudo setenforce 0关闭SELinux,重启容器如果问题解决,即可确认是SELinux限制导致 - 永久修复:两种可选方式
- 给宿主机目标目录加允许容器访问的SELinux标签:
sudo chcon -Rt svirt_sandbox_file_t $PWD - 直接修改容器运行命令的挂载参数,添加权限标签,把运行脚本第6行改为:
其中小写-v $PWD:/app:z ${app}z代表目录可被多个容器共享读写,大写Z代表仅允许当前容器访问,可根据你的场景选择。 - 给宿主机目标目录加允许容器访问的SELinux标签:
方案2:修正用户与目录权限配置
你当前的Dockerfile只创建了自定义用户,没有切换运行用户,也没有给对应目录开放权限:
- 如果你要以创建的自定义用户运行容器,在Dockerfile的
CMD指令前添加一行:USER $UNAME - 如果你需要用root运行容器,可以在Dockerfile的
COPY指令后添加一行,提前开放会话目录权限:RUN mkdir -p /app/flask_session && chmod 777 /app/flask_session - 也可以在运行容器时直接指定使用宿主机当前用户的UID/GID运行,保证权限匹配:
docker run -it -d -p 56733:80 \ --name=${app} \ --user $(id -u):$(id -g) \ -v $PWD:/app:z ${app}
方案3:规避挂载目录存储会话(生产环境推荐)
会话缓存数据不需要持久化到宿主机的情况下,直接修改flask配置,将会话存储路径改为容器内的非挂载目录,彻底避免权限问题:
在你的Flask配置代码中添加:
SESSION_FILE_DIR = '/tmp/flask_session'
容器内的/tmp目录默认对所有进程开放写入权限,不会出现权限报错,也不会导致登录循环。
内容的提问来源于stack exchange,提问作者Sceler
相关产品推荐
相关产品推荐

