Docker+Nginx+uWSGI部署Flask时上传文件遇权限拒绝错误
Flask生产部署(Docker+Nginx+uWSGI)上传图片权限错误解决
问题现象
使用Docker、Nginx和uWSGI部署Flask应用到生产环境时,应用整体运行正常,但上传图片至static/uploads目录时触发权限错误:
PermissionError: [Errno 13] Permission denied: 'static/uploads/timyoutube.jpg'
手动在容器内可正常写入文件,开发模式下用flask run启动应用也无此问题。
相关配置文件
Dockerfile
# syntax=docker/dockerfile:1 FROM python:3.8-slim-buster WORKDIR /flask_app RUN apt-get clean \ && apt-get -y update RUN apt-get -y install nginx \ && apt-get -y install python3-dev \ && apt-get -y install build-essential EXPOSE 8080 COPY requirements.txt requirements.txt RUN pip install -r requirements.txt --src /usr/local/src COPY . . COPY nginx.conf /etc/nginx RUN chmod +x ./start.sh CMD ["./start.sh"] # CMD [ "python3", "-m" , "flask", "--app", "main", "run", "--host=0.0.0.0", "-p", "5001"]
uwsgi.ini
[uwsgi] module = main:app uid = www-data gid = www-data master = true processes = 5 #socket = /tmp/uwsgi.socket socket = 127.0.0.1:8080 chmod-socket = 666 vacuum = true die-on-term = true
nginx.conf
user www-data; worker_processes auto; pid /run/nginx.pid; events { worker_connections 1024; use epoll; multi_accept on; } http { access_log /dev/stdout; error_log /dev/stdout; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; index index.html index.htm; # Configuration containing list of application servers upstream uwsgicluster { server 127.0.0.1:8080; # server 127.0.0.1:8081; # .. # . } server { listen 8888 default_server; listen [::]:8888 default_server; server_name localhost; root /var/www/html; location / { include uwsgi_params; uwsgi_pass uwsgicluster; uwsgi_read_timeout 1h; uwsgi_send_timeout 1h; proxy_send_timeout 1h; proxy_read_timeout 1h; } } }
问题原因
从uWSGI配置可知,应用进程是以www-data用户/组身份运行的,但static/uploads目录通过COPY . .复制到容器后,默认所有者为root用户,www-data组用户没有该目录的写入权限。
开发模式下flask run默认以root用户启动,手动在容器内操作也通常使用root用户,因此不会触发权限问题。
解决方案
方法一:修改目录权限(生产环境推荐)
在Dockerfile中COPY . .指令之后添加以下命令,确保上传目录的所有者和权限符合uWSGI运行用户的要求:
RUN mkdir -p static/uploads && \ chown -R www-data:www-data static/uploads && \ chmod -R 755 static/uploads
mkdir -p:确保目录存在(若本地static/uploads为空,COPY指令可能不会创建该目录)chown:将目录及文件的所有者改为uWSGI运行的www-data用户组chmod 755:赋予所有者读写执行权限,组和其他用户读执行权限,兼顾安全与功能
方法二:调整uWSGI运行用户(不推荐)
若临时测试需要,可修改uWSGI配置,让进程以root用户运行,但此做法会带来安全风险,生产环境禁止使用:
修改uwsgi.ini中的uid和gid字段:
uid = root gid = root
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

