部署于Elastic Beanstalk的Python Flask服务无法保存上传文件
Flask在EC2部署时文件保存接口返回500错误解决
你这个场景本地测试正常、移除file.save()逻辑后接口正常返回,问题完全集中在文件保存环节的路径/权限配置上,和上传大小限制、接口逻辑无关,按以下步骤排查即可:
- 首先排查路径不存在问题
你代码中UPLOAD_FOLDER = os.getcwd() + '/uploads'的写法存在隐患:os.getcwd()获取的是启动Flask进程时的工作目录,不是代码文件本身所在的目录。本地测试时你通常在代码文件所在目录启动服务,路径匹配所以正常;EC2上如果通过systemd、gunicorn、supervisor等托管服务启动进程,工作目录往往和代码目录不一致,会导致拼接出来的uploads目录实际不存在,保存文件时直接抛错。
先把路径定义改成基于代码文件位置的绝对路径,彻底避免工作目录的影响:
改完后SSH登录EC2,确认代码同级目录下的# 替换原来的UPLOAD_FOLDER定义 BASE_DIR = os.path.abspath(os.path.dirname(__file__)) UPLOAD_FOLDER = os.path.join(BASE_DIR, 'uploads')uploads文件夹存在,不存在就手动创建:# 进入代码所在目录后执行 mkdir -p uploads - 其次排查目录写入权限问题
这是EC2部署最常见的触发点:运行Web服务的用户对uploads目录没有写入权限。本地测试时你用自己的账号启动服务,对自己建的目录天然有读写权限;EC2上如果用Nginx、Gunicorn部署,服务通常运行在www-data、nginx这类独立用户下,默认没有你个人用户目录的写入权限。
根据你的服务运行用户给目录赋权即可,比如常见的Gunicorn+Nginx部署场景:
如果你是直接用# 先进入代码所在目录,给uploads目录设置服务运行用户的所有权 chown -R www-data:www-data ./uploads chmod 755 ./uploadspython app.py启动测试服务,把目录所有者改成你当前登录EC2的用户即可。 - 快速定位错误的小技巧
如果以上两步调整完还是报错,临时给保存逻辑加异常捕获,直接打印具体错误信息,不用盲目排查:@application.route("/test-upload", methods=["POST"]) def test_upload(): file = request.files['file'] filename = secure_filename(file.filename) save_path = os.path.join(application.config['UPLOAD_FOLDER'], filename) try: file.save(save_path) except Exception as e: # 直接把具体错误信息返回,就能看到是权限不足、路径不存在还是其他问题 return f"文件保存失败:{str(e)}", 500 return str(save_path)
内容的提问来源于stack exchange,提问作者yankeedoodle
相关产品推荐
相关产品推荐

