前言
之前用Flask框架开发了一个Python的Web项目,使用Nginx和uWSGI部署起来感觉挺麻烦,过程中还因为对Flask框架的不熟悉,花了好长时间才把应用完全部署起来。下面分享部署成功的相关配置以及部署Flask项目时极可能犯的一个小错误。
一、 配置
1. Flask Web项目源码
Nginx使用的版本是1.6.1,uWSGI是2.0.8,Flask是0.10.1。在Linux环境下安装好Nginx、uWSGI和Flask之后,将使用Flask框架开发的web项目源码放到Linux服务器的某个目录下,例如/data/web_app/testpro。以最简单的一个Flask web项目作为例子,其代码只有test.py一个源码文件,内容如下:
1 from flask import Flask 2 app = Flask(__name__) 3 4 @app.route('/') 5 def index(): 6 return 'Hello World!' 7 8 if __name__ == '__main__': 9 app.run()
那test.py的完整路径就是/data/web_app/testpro/test.py。
2. 配置Nginx
在Nginx的安装目录找到Nginx的配置文件,安装目录一般是/usr/local/nginx,配置文件是nginx.conf,对其进行编辑,使得Nginx能够加载uwsgi。
1 location / { 2 include uwsgi_params; 3 uwsgi_pass 127.0.0.1:5000; 4 }
3. 为Flask Web项目添加uWSGI配置文件
在/data/web_app/testpro目录下添加一个uWSGI的配置文件test_config.ini,内容如下:
1 [uwsgi] 2 socket = 127.0.0.1:5000 #注: 指定某个固定端口 3 processes = 4 #注:跑几个进程,这里用4个进程 4 threads = 2 5 master = true 6 pythonpath = /data/web_app/testpro 7 module = test 8 callable = app 9 memory-report = true
其中几个主要参数的含义如下:
- pythonpath:表示项目目录
- module:表示项目启动模块,如上例为test.py,这里就为test
- callable:表示Flask项目的实例名称,上例代码中app = Flask(__name__),所以这里为app
- socket:表示和Nginx通信的地址和端口,和Nginx配置里的uwsgi_pass一致。
- processes:表示开启多少个子进程处理请求。
- threads:每个进程的线程数。
之后启动uWSGI:
1 uwsgi -d /var/log/uwsgi.log --ini /data/web_app/testpro/test_config.ini
其中,-d参数指明日志路径为/var/log/uwsgi.log。
接下来,按照Nginx配置文件中server项下的listen和server_name参数对应的值使用浏览器对项目进行访问,看到输出 “Hello World!” 则表示部署成功。
二、 使用Session功能莫忘配置SECRET_KEY
如果Flask的项目使用了Session, Cookies等功能,需要配置SECRET_KEY的值,不然使用上面的方式部署之后,相关涉及Session, Cookies的操作会一直报500的Internal server error,如果是像我这样的新手,那问题定位起来就会很辛苦。明明已经按照标准的教程配置好了,为什么做登录操作的时候还一直报错呢?最后发现是没有配置SECRET_KEY,差点吐血而亡!
这个错误特别容易发生在使用Flask自带的服务器转到上述部署方式的过程中,例如对于上面的Flask web项目,使用Flask自带的服务器运行时,如果配置了SECRET_KEY参数,代码可能会是这样的:
1 from flask import Flask 2 app = Flask(__name__) 3 4 @app.route('/') 5 def index(): 6 return 'Hello World!' 7 8 if __name__ == '__main__': 9 app.secret_key = 'abcdef' 10 app.run(host='xx.xx.xx.xx', port=8080)
1 from flask import Flask 2 app = Flask(__name__) 3 4 app.secret_key = 'abcdef' 5 6 @app.route('/') 7 def index(): 8 return 'Hello World!' 9 10 if __name__ == '__main__': 11 app.run(host='xx.xx.xx.xx', port=8080)
原文地址:http://juxuan.fu.blog.163.com/blog/static/112129259201411188132562/