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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:40:24