在 CentOS 上使用 Nginx/uWSGI 部署 Flask 网站应用

在本地 Mac 环境下熟悉一阵 Python Flask Web 应用开发与测试运行之后,开始服务器部署操作,以便了解生产环境下 Flask 应用的调试部署。

基本环境与组件

  • 服务器 - DigitalOcean VPS CentOS 6.7 x32 $5/月,优惠购买链接
  • Nginx - 反向代理
  • Python - 2.7.10
  • Flask/uWSGI 等 Python 包为最新版 Nginx-WSGI-Flask app

服务器初始化

DigitalOcean 新增Droplet,选择环境为 CentOS 6.7 32位,首先使用下列命令安装一系列必要的软件

yum -y update  
yum install gcc  
yum install -y zlib-devel openssl-devel sqlite-devel bzip2-devel  
yum install vim  
yum install wget  
yum install xz  

Python安装

为了与本地开发使用的 Python 版本一致,需要抛弃 CentOS 中自带的 Python2.6老旧版本,使用 Python2.7.10。

  • 首先复制一份 Python 启动执行文件的副本
cp /usr/bin/python /usr/bin/python2.6  
  • 修改 yum 配置文件中对 Python 的引用
vim /usr/bin/yum  

#!/usr/bin/python

修改为

#!/usr/bin/python2.6

保存退出

  • 下载安装 Python2.7.10

Python 各个版本副本列表

下载2.7.10并编译安装

wget http://www.python.org/ftp/python/2.7.10/Python-2.7.10.tar.xz  
xz -d Python-2.7.10.tar.xz  
tar -xvf Python-2.7.10.tar  
cd Python-2.7.10  
./configure --prefix=/usr/local/python2.7
make && make altinstall  

安装完成后,使用下列命令分别确定当前默认 Python 的路径与版本

which python  
python -V  

一般情况下,新安装的 Python 无法直接替换旧版本 Python,需要通过建立软链接:

ln -s /usr/local/python2.7/bin/python2.7 /usr/bin/python  

完成后再次确认默认 Python 路径与版本

Python 包管理工具 Pip

wget --no-check-certificate https://bootstrap.pypa.io/get-pip.py  
python get-pip.py  

虚拟环境及扩展

由于 Flask 应用开发中需要使用多种扩展,为了避免污染默认的 Python 环境文件,使用虚拟 Python 环境可以有效的独立不同应用的 Python 环境

pip install virtualenv  

为了统一管理,在/home 文件夹下创建了 apps 文件夹,用于多个应用保存的位置,在 apps 下新建文件夹 myapp1,作为第一个应用文件夹。

首先为将要创建的应用设置虚拟环境以及安装一些扩展。

激活虚拟环境

cd myapp1  
virtualenv venv  
. venv/bin/activate

可以使用deactivate命令退出虚拟环境

安装 flask,uWSGI

pip install flask  
pip install uwsgi  

创建应用

下面演示创建基本的 "hello python"单页应用。

假设当前命令行位于 myapp1 文件夹下

mkdir app  
cd app  
touch __init__.py  
vim __init__.py  

__init__.py文件中输入如下代码:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():  
    return 'Hello Python'

if __name__ == '__main__':  
    app.run()

使用快捷键 :wq 保存并退出编辑,继续回到上级文件夹 myapp1,新建文件 manage.py 并编辑:

from app import app

if __name__ == "__main__":  
    app.run()

配置 uWSGI 服务器网关服务

uWSGI 可以以前台或后台方式运行,前台方式使用 ctrl+c 即可终止,后台方式需要通过ps -ef | grep uwsgi方式查找 pid,然后使用kill pid方式终止进程。

前台方式从 manage.py 启动应用:

uwsgi --socket 127.0.0.1:8080 -w manage:app  

后台方式从 manage.py 启动应用:

uwsgi --socket 127.0.0.1:8080 -w manage:app &  

安装配置 Nginx 代理

sudo su -c 'rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm'

sudo yum install -y nginx  

Nginx 基本操作命令:

sudo service nginx start

sudo service nginx stop

sudo service nginx restart  

查看 Nginx 基本配置文件:

cat /etc/nginx/nginx.conf  

找到扩展配置存放的文件夹(一般为/etc/nginx/conf.d),并新建一个 myapp1.conf 并添加服务配置,具体配置请参考下方:

upstream uwsgicluster {  
    server 127.0.0.1:8080;
}
#
# The default server
#
server {

    # Running port
    listen 80;
    # Host
    server_name www.yourdomain.com;

    # Settings to by-pass for static files 
    location ^~ /static/  {

        # Example:
        # root /full/path/to/application/static/file/dir;
        root /home/apps/myapp1/app/static/;

    }

    # Serve a static file (ex. favico) outside static dir.
    location = /favico.ico  {

        root /app/favico.ico;

    }

    # Proxying connections to application servers
    location / {

        include            uwsgi_params;
        uwsgi_pass         uwsgicluster;

        proxy_redirect     off;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;

    }
    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

记得修改配置后重启 Nginx 服务。