在Ubuntu 16.04上部署Flask项目

3,483 阅读5分钟

前言

在本文中,我们将在Ubuntu 16.04搭建一个很简易的flask项目,其中包含了如何设置uWSGI应用程序服务器和启动应用程序,以及设置nginx作为反向代理。

首先,uWSGI是什么

Flask项目是一个web应用程序,安装了python环境,它可以自己启动,但是它启动后服务器就不能搞别的事情了,而且服务还容易挂,这就需要一个可以并发、24小时运行还不容易挂的代理服务器,那么Nginx就登场了,但是有一个问题,python web框架编写的应用程序与后台服务器之间的规范是WSGI规范,nginx恰好就不支持这个规范,那就得一个支持这个规范的web服务器,uWSGI就登场了。

各自职责

  1. nginx 做为代理服务器:负责静态资源发送(js、css、图片等)、动态请求转发以及结果的回复;
  2. uWSGI 做为后端服务器:负责接收 nginx 请求转发并处理后发给 Flask 应用以及接收 Flask 应用返回信息转发给 nginx;
  3. 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启动一下,首先要指定sockethttp协议,以便应用程序启动后可以在其他地方通过服务器的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