关于Pillow安装不当导致Server Error(500)问题的解决
基于Django开发个人博客(https://www.solutionworks.cn)时,选择文章对应缩略图,完成文章编写并提交保存时,发生错误,在浏览器中的错误信息为:Server Error(500)。本文记录了问题的发现与排查解决过程。
一、基本条件
本文使用的Django版本为3.0版,python版本为3.8.3,MySQL为5.7.26,uWSGI版本为2.0.19.1,Nginx版本为1.14.1,Pillow版本为7.2.0,系统为CentOS 8.0。
二、问题描述
在博客系统完成部署后,在服务器端文章发布环节,选择文章对应缩略图,完成文章编写并提交保存时,发生错误,在浏览器中的错误信息为:Server Error(500)。发布文章时,如果不选择文章对应缩略图,点击保存按钮,一切正常;在本地选择文章对应缩略图后,发布文章时并不存在上述问题。显然,问题很可能出在文件上传保存环节(此时并没有意识到是支持包安装错误导致的问题)。
既然在本地环境测试文章发布功能一起正常,那么很大概率在代码、环境设置、文件上传路径方面应该不会存在问题。但是,还是进行了核实,核实的环节包括:
- 上传目录设置
在服务器端,建立了media目录,settings.py文件中也进行了相应的设置。
(1)Article的Model声明部分
content = UEditorField('内容', width=800, height=500,
toolbars="full", imagePath="upimg/", filePath="upfile/",
upload_settings={"imageMaxSize": 1204000},
settings={}, command=None, blank=True
)
代码正常,应该没有问题。
(2)服务器端文件存放目录核查
服务器端文件目录media下的子目录 article_img 用来存放每一个文章对应的图片(类似文章封面预览图),目前无法保存。
服务器端文件目录media下的子目录upimg 用来存放每一篇文章内容里面的图片,文章保存之后,文章内容里面的图片目前可以保存至upimg目录下。目录 article_img和upimg 读写权限是一致。
2、解决方法
(1)查看Nginx访问记录文件
在Nginx访问记录文件(access.log)中,发现如下相关信息:
XXX.XXX.XXX.XXX - - [26/Aug/2020:11:41:35 +0800] "GET /admin/jsi18n/HTTP/1.1"200 7722 "http://xxx.xxx.xxx.xxx/admin/blog/article/3/change/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
XXX.XXX.XXX.XXX - - [26/Aug/2020:11:41:35 +0800] "GET /ueditor/controller/?imageMaxSize=1204000&imagePathFormat=upimg%2F&filePathFormat=upfile%2F&action=config&&noCache=1598413295748 HTTP/1.1" 200 2171 "http://xxx.xxx.xxx.xxx/admin/blog/article/3/change/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
XXX.XXX.XXX.XXX - - [26/Aug/2020:11:42:11 +0800] "POST /admin/blog/article/3/change/ HTTP/1.1" 500 145 "http://xxx.xxx.xxx.xxx/admin/blog/article/3/change/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
error.log中的信息为:2020/08/26 11:41:14 [error] 208449#0: *1 directory index of "/home/iblog/media/" is forbidden, client: XXX.XXX.XXX.XXX, server: xxx.xxx.xxx.xxx, request: "GET /media/ HTTP/1.1", host: "xxx.xxx.xxx.xxx", referrer: http://xxx.xxx.xxx.xxx/
(2)数据库记录查看确认
在服务器端,连接MySQL数据库,通过执行如下SQL语句:
select itle,img,status,views,created_time,modified_time from blog_article;
查询服务器数据库中数据表blog_article的内容,结果如下:
A、上图中绿色方框内, img 字段的2条记录内容是在本地测试时生成的记录,在本地导出数据库内容,在服务器端通过 source 命令导入数据库,表明在本地写入数据表 blog_article 的字段 img 是没有问题的;
B、上图中黄色方框内, img字段没有内容,是在部署到服务器后进行测试,表明在服务器端,上传图片的名称(含路径)根本没有写入到数据表 blog_article 的 img 字段中 。
由此,可以猜测:
(1)在服务器端,写入数据表 blog_article 的字段 img 产生异常;
(2)产生字段写入异常之后,估计导致保存文章的过程中止,因此,在服务器端的目录”media/article_img/2020/08/01“中没有存入文章对应封面图片。
3、排查服务器端支持包的安装情况
登录服务器端,进入虚拟环境,查看支持包的安装情况。
指令:workon py3.8-venv,pip list
发现在虚拟环境下,Pillow已经安装,退出虚拟环境。执行pip list命令,发现Pillow并没有安装。
该不是在虚拟环境中安装了Pillow,而在CentOS系统中没有安装Pillow的原因吧?简直无语了……
到此,问题基本明朗了,执行如下命令:
pip install pillow
完成Pillow 安装,重新启动Nginx和uWSGI Web服务器,重新测试,功能一切正常。
重新进入虚拟环境,卸载Pillow 后,再次测试,功能正常。
四、结论
- 表明只在 CentOS系统中安装 Pillow 即可,虚拟环境中根本不需要安装 Pillow
- 始终要明确开发应用过程中所用到的支持包,确保在部署应用时全部安装,否在在后续部署测试过程中导致的问题以及解决问题的成本比较高。