Day 08 - Amazon Linux 2 上将 Django 与 Nginx 合并
先前我们都是直接使用 Django 所建立的网页伺服器,但是毕竟 Django 并非专注于网页伺服器这个领域,所以在 Python PEP 3333 号文件中有提出了一个 Python Web Server Gateway Interface (wsgi)规范,就是用来协助网站伺服器与 Python 框架结合的主要协议,下图就是 Nginx 结合 Django 的架构,一开始,我们都是使用浏览器直接存取 Django,透过这个框架,我们发现需要有 Nginx 网页伺服器,透过实作 Python PEP 3333 的 mod_wsgi 模组来与 uWSGI 这个行程沟通,而沟通的介面是透过 socket,而 uWSGI 则是利用 uWSGI.ini 档案的配置,取得 Django 框架的设定,而与 Django 沟通。安装设定成功后,就可以直接透过 http://[EC2_IPv4]/imgUpload/ 这个方式来跟 Django RESTful Web API 沟通。
图 1、 Nginx 结合 Django 的架构
整个步骤如下:
- 安装 Nginx
- 设定 Nginx
- 安装 uWSGI
- 设定 uWSGI.ini 并启动 uWSGI
- 测试 Django 与 Nginx 合并结果
安装 Nginx
登录 EC2,安装 Nginx,因为我们使用的是 Amazon Linux 2 所以要输入 sudo amazon-linux-extras install nginx1 来进行安装,而非一般的 yum 套件安装。
# 检查是否已经安装
rpm -qa | grep nginx
# 安装 Nginx
sudo amazon-linux-extras install nginx1
# 启动 Nginx
sudo systemctl start nginx
# 设定开机后 Nginx 自动启动
sudo systemctl enable nginx
# 以下两个指令可以在排查错误时使用
# 检查 nginx 状态
sudo systemctl status nginx
# 关闭 nginx
sudo systemctl stop nginx
打开浏览器输入 EC2 的公有 IPv4 地址,确认网站伺服器是否已经正常启动。
图 2、 Nginx 网站伺服器预设画面
设定 Nginx
打开 nginx 的设定档案,记得要用管理者的权限打开,找到 server 的设定区块,新增这两个设定,images 是用来设定静态网页,也就是由 nginx 直接处理,主要是用来观看上传图片或是处理后的图片;而 / 目录则是对应到 uwsgi 这个应用程式,这个应用程式会将请求转给 Django 框架。
sudo vi /etc/nginx/nginx.conf
/etc/nginx/nginx.conf
location /images {
alias /home/ec2-user/fishRecognition/fishsite/upload;
}
location / {
uwsgi_pass 127.0.0.1:8000;
include /etc/nginx/uwsgi_params;
}
下图显示设定档的上下内容。
图 3、 Nginx 网站伺服器组态设定
接着只要重新启动 nginx 伺服器,就可以让设定生效。
sudo systemctl restart nginx
但使用者透过浏览器还是看不到期望看到的图片,这时候建议观看 nginx 的存取记录,需要切换成管理者,方可有权限可以看到 nginx 的错误讯息,如下图所示。
图 4、 Nginx 的错误讯息
可以发现,出现 Permission denied 这样的错误讯息,主要是因为 nginx 网页伺服器无法访问 ec2-user 这个使用者的个人目录,所以需要打开进入权限,才可以解决这个问题。指令如下:
# 切换成管理者
sudo su -
# 观看 nginx 错误记录
more /var/log/nginx/error.log
# 打开 ec2-user 使用的个人目录,允许任何人进入该目录
chmod o+x ~ec2-user/
# 回到 ec2-user 使用者
exit
再次刷新浏览器就可以看到图片,如下图所示。
图 5、 Nginx 网站伺服器静态网页的画面
安装并设定 uWSGI
使用 pip3 安装 uWSGI 套件。
pip3 install uwsgi
先确认一下所在目录 /home/ec2-user/fishRecognition/fishsite,开始编辑 uWSGI 的设定档 uwsgi.ini 。
cd ~ec2-user/fishRecognition/fishsite
vi uwsgi.ini
uwsgi.ini
[uwsgi]
; 指定 Django 专案目录
chdir = /home/ec2-user/fishRecognition/fishsite
; 指定 Django 专案名称
module=fishsite.wsgi
master = True
pidfile = /tmp/fishsite-master.pid
vacuum = True
max-requests = 5000
daemonize = /tmp/fishsite.log
; 指定 socket
socket = 127.0.0.1:8000
; 指定虚拟环境目录
pythonpath = /home/ec2-user/fishRecognition/lib/python3.7/site-packages/:/home/ec2-user/fishRecognition/fishsite
如下图,再次确认 Django 的专案目录结构,确定无误后,运行 uWSGI 并指定参数档。
uwsgi --ini uwsgi.ini
图 6、 确认 Django 专案目录结构
正常不会有任何讯息输出,如果要查错的话,可以打开 /tmp/fishsite.log 这个档案,看看有何存取异常的记录,此外,也可以善用以下指令来进行除错。
# 这里检查 uwsgi 的程式,查看是否正常运作
ps -ef | grep uwsgi
# 删除所有 uwsgi 的程式
killall -s INT uwsgi
# 重启 uwsgi 服务
uwsgi --reload /tmp/fishsite-master.pid
测试 Django 与 Nginx 合并结果
打开 ARC,因为我们先前有实作 get 与 post 两个方法,先测试比较简单的 get 方法,结果如下图所示,当我们选择 fid 为 2 时就可以顺利回传指定的鱼类资讯,这表示 Django 与 Nginx 整合成功,有依照规划的方式运作。
图 7、 检测 Django 与 Nginx 合并结果
参考资料
- PEP 3333 – Python Web Server Gateway Interface, https://www.python.org/dev/peps/pep-3333/
- The uWSGI project, https://uwsgi-docs.readthedocs.io/en/latest/
- mod_wsgi, https://modwsgi.readthedocs.io/en/master/
- 【Python 教學】uWSGI 配置參數講解, https://www.maxlist.xyz/2020/06/20/flask-uwsgi/
- Django项目框架部署到远端服务器, https://zhuanlan.zhihu.com/p/258849678
- Nginx + uWSGI + Python + Django搭建一款只属于自己的壁纸网站, https://zhuanlan.zhihu.com/p/134014310
- 如何使用 Apache 和 mod_wsgi 托管 Django, https://docs.djangoproject.com/zh-hans/3.2/howto/deployment/wsgi/modwsgi/