前言
在本文中,我们将在Ubuntu 16.04搭建一个很简易的flask项目,其中包含了如何设置uWSGI应用程序服务器和启动应用程序,以及设置nginx作为反向代理。
首先,uWSGI是什么
Flask项目是一个web应用程序,安装了python环境,它可以自己启动,但是它启动后服务器就不能搞别的事情了,而且服务还容易挂,这就需要一个可以并发、24小时运行还不容易挂的代理服务器,那么Nginx就登场了,但是有一个问题,python web框架编写的应用程序与后台服务器之间的规范是WSGI规范,nginx恰好就不支持这个规范,那就得一个支持这个规范的web服务器,uWSGI就登场了。
各自职责
- nginx 做为代理服务器:负责静态资源发送(js、css、图片等)、动态请求转发以及结果的回复;
- uWSGI 做为后端服务器:负责接收 nginx 请求转发并处理后发给 Flask 应用以及接收 Flask 应用返回信息转发给 nginx;
- Flask 应用收到请求后处理数据并渲染相应的返回页面给 uWSGI 服务器。
开始
搞清楚逻辑,下面就开始了...
现在应该没有 python2 什么事了,我们默认就 python3 了,Ubuntu服务器默认有apt-get包管理器,先使用apt-get安装需要的东西
sudo apt-get update
sudo apt-get install python3-pip python3-dev nginx
安装好了pip,再用pip安装python的虚拟运行环境
sudo pip3 install virtualenv
新建一个项目目录myproject
mkdir ~/myproject
cd ~/myproject
创建一个虚拟环境
virtualenv myprojectenv
进入虚拟环境
source myprojectenv/bin/activate
如果命令行最前面有一个(myprojectenv),就说明进入虚拟环境了
下面我们在虚拟环境安装python依赖包
特别注意,在虚拟环境中要使用pip,而不能使用pip3
pip install uwsgi flask
有了flask,我们就创建一个简单的应用程序
nano ~/myproject/myproject.py
文件内容如下:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
文件完成后,按Ctrl+X,然后按Y,回车
启动程序默认端口是5000,服务器可能并没有启用,我们先启用端口
sudo ufw allow 5000
启动
python myproject.py
接下来就可以在本地浏览器中访问服务器地址,看到我们的程序内容
http://服务器的IP地址:5000
完成后,按几次Ctrl+C停止Flask开发服务器
测试uWSGI服务
接下来,我们创建一个WSGI入口点,这个文件将告诉uWSGI服务器如何与我们的Flask应用程序进行交互。
nano ~/myproject/wsgi.py
写入以下内容:
from myproject import app
if __name__ == "__main__":
app.run()
保存并关闭文件。
现在有了入口文件,那我们试着用uWSGI启动一下,首先要指定socket和http协议,以便应用程序启动后可以在其他地方通过服务器的IP地址访问,最后指定入口文件以及模块
uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
然后在本地浏览器访问
http://服务器的IP地址:5000
按几次Ctrl+C终止服务
下面我们就要退出虚拟环境了
deactivate
创建一个uWSGI配置文件
我们已经测试了uSWGI可以启动应用程序,但我们希望长期使用的东西更稳定一些。首先,我们创建一个uWSGI的配置文件
nano ~/myproject/myproject.ini
文件内容如下
[uwsgi]
; 声明这个配置文件是针对uwsgi
module = wsgi:app
; 指定入口
master = true
; 以主模式启动
processes = 5
; 生成5个工作进程
socket = myproject.sock
chmod-socket = 660
vacuum = true
; 我们上面用的socket是http的,而这里配置的是Unix的socket,因为这些组件在一台电脑上运行,所以Unix socket更快更安全。之后还会在我们的工程下面生成一个`myporject.sock`文件
die-on-term = true
; 确保原始系统跟uSWGI保持一致
完成后,保存并关闭文件
创建系统服务
下面我们要创建一个系统服务,用系统服务启动uWSGI给Flask应用程序提供服务
sudo nano /etc/systemd/system/myproject.service
文件内容如下
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=你的用户名
Group=www-data
WorkingDirectory=/home/你的用户名/myproject
Environment="PATH=/你的用户名/ubuntu/myproject/myprojectenv/bin"
ExecStart=/home/你的用户名/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
[Install]
WantedBy=multi-user.target
注意:一定要正确填写的当前用户的用户名,输入命令
pwd就可以查看当前的绝对路径,/home/后面的就是你的用户名
完成后,保存并关闭文件
下面我们就启动这个服务
sudo systemctl start myproject
sudo systemctl enable myproject
配置Nginx
我们的uWSGI应用程序服务器应该已启动并正在运行,下面我们就需要nginx接受web请求,并传给socket
首先在Nginx的sites-available目录中创建一个新的服务器块配置文件
sudo nano /etc/nginx/sites-available/myproject
配置内容如下
server {
listen 80;
server_name server_domain_or_IP;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/你的用户名/myproject/myproject.sock;
}
}
server_name 后面填你服务器的IP地址或者已经解析了的域名地址
完成后,保存并关闭文件
要启用我们刚才的配置,就得把配置文件链接到sites-enabled目录
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
我们首先测试一下 配置文件有没有语法错误
sudo nginx -t
如果没有任何指示,重新启动nginx
sudo systemctl restart nginx
我们现在的端口是80端口,不需要5000了,同时我们允许防火墙访问nginx服务器
sudo ufw delete allow 5000
sudo ufw allow 'Nginx Full'
完成后,重新启动一下我们的myproject服务
sudo systemctl restart myproject
现在,你在浏览器中访问你服务器的域名或者IP地址
http://server_domain_or_IP
大功告成....
结束
首先把你本地的Flask项目生成requirement.txt,然后把项目搬进服务器的~/myproject/目录下(我的做法是先把项目上传到git,然后在服务器上pull下来),然后进入虚拟环境,根据requirement.txt加载项目所有依赖包,同时不要忘记把wsgi.py中的from myproject import app改成你项目的入口文件。
每次做完修改,都必须要sudo systemctl restart myproject