Flask 部署和分發

到目前爲止,啓動Flask應用都是經過」app.run()」方法,在開發環境中,這樣當然可行,不過到了生產環境上,勢必須要採用一個健壯的,功能強大的Web應用服務器來處理各類複雜情形。同時,因爲開發過程當中,應用變化頻繁,手動將每次改動部署到生產環境上非常繁瑣,最好有一個自動化的工具來簡化持續集成的工做。本篇,咱們就會介紹如何將上一篇中Flask的應用程序自動打包,分發,並部署到像Apache, Nginx等服務器中去。html

使用setuptools打包Flask應用

首先,你要了解基本的使用setuptools打包分發Python應用程序的方法。接下來,就讓咱們開始寫一個」setup.py」文件:python

from setuptools import setup
 
setup(
    name='MyApp',
    version='1.0',
    long_description=__doc__,
    packages=['myapp','myapp.main','myapp.admin'],
    include_package_data=True,
    zip_safe=False,
    install_requires=[
        'Flask>=0.10',
        'Flask-Mail>=0.9',
        'Flask-SQLAlchemy>=2.1'
    ]
)

把文件放在項目的根目錄下。另外,還要寫一個」MANIFEST.in」文件:nginx

recursive-include myapp/templates *
recursive-include myapp/static *

編寫完畢後,你能夠建立一個乾淨的虛擬環境,而後運行安裝命令試下效果。apache

python setup.py install

使用Fabric遠程部署Flask應用

一樣,你須要先了解如何使用Fabric來遠程部署Python應用。而後,咱們來編寫」fabfile.py」文件:api

from fabric.api import *
 
env.hosts = ['example1.com', 'example2.com']
env.user = 'bjhee'
 
def package():
    local('python setup.py sdist --formats=gztar', capture=False)
 
def deploy():
    dist = local('python setup.py --fullname', capture=True).strip()
    put('dist/%s.tar.gz' % dist, '/tmp/myapp.tar.gz')
    run('mkdir /tmp/myapp')
    with cd('/tmp/myapp'):
        run('tar xzf /tmp/myapp.tar.gz')
        run('/home/bjhee/virtualenv/bin/python setup.py install')
    run('rm -rf /tmp/myapp /tmp/myapp.tar.gz')
    run('touch /var/www/myapp.wsgi')

上例中,」package」任務是用來將應用程序打包,而」deploy」任務是用來將Python包安裝到遠程服務器的虛擬環境中,這裏假設虛擬環境在」/home/bjhee/virtualenv」下。安裝完後,咱們將」/var/www/myapp.wsgi」文件的修改時間更新,以通知WSGI服務器(如Apache)從新加載它。對於非WSGI服務器,好比uWSGI,這條語句能夠省去。服務器

編寫完後,運行部署腳本測試下:併發

fab package deploy

使用Apache+mod_wsgi運行Flask應用

Flask應用是基於WSGI規範的,因此它能夠運行在任何一個支持WSGI協議的Web應用服務器中,最經常使用的就是Apache+mod_wsgi的方式。上面的Fabric腳本已經完成了將Flask應用部署到遠程服務器上,接下來要作的就是編寫WSGI的入口文件」myapp.wsgi」,咱們假設將其放在Apache的文檔根目錄在」/var/www」下。app

activate_this = '/home/bjhee/virtualenv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
 
import os
os.environ['PYTHON_EGG_CACHE'] = '/home/bjhee/.python-eggs'
 
import sys;
sys.path.append("/var/www")
 
from myapp import create_app
import config
application = create_app('config')

注意上,你須要預先建立配置文件」config.py」,並將其放在遠程服務器的Python模塊導入路徑中。上例中,咱們將」/var/www」加入到了Python的模塊導入路徑,所以能夠將」config.py」放在其中。另外,記得用setuptools打包時不能包括」config.py」,以避免在部署過程當中將開發環境中的配置覆蓋了生產環境。異步

在Apache的」httpd.conf」中加上腳本更新自動重載和URL路徑映射:socket

WSGIScriptReloading On
WSGIScriptAlias /myapp /var/www/myapp.wsgi

重啓Apache服務器後,就能夠經過」http://example1.com/myapp」來訪問應用了。

使用Nginx+uWSGI運行Flask應用

要先準備好Nginx+uWSGI的運行環境,而後編寫uWSGI的啓動文件」myapp.ini」:

[uwsgi]
socket=127.0.0.1:3031
callable=app
mount=/myapp=run.py
manage-script-name=true
master=true
processes=4
threads=2
stats=127.0.0.1:9191
virtualenv=/home/bjhee/virtualenv

再修改Nginx的配置文件,Linux上默認是」/etc/nginx/sites-enabled/default」,加上目錄配置:

location /myapp {
    include uwsgi_params;
    uwsgi_param SCRIPT_NAME /myapp;
    uwsgi_pass 127.0.0.1:3031;
}

重啓Nginx和uWSGI後,就能夠經過」http://example1.com/myapp」來訪問應用了。

你也能夠將咱們的應用配置爲虛擬服務器,只須要將上述uWSGI的配置移到虛擬服務器的配置文件中便可。關於Nginx虛擬服務器的配置,能夠參考我以前的文章

使用Tornado運行Flask應用

Tornado的強大之處在於它是非阻塞式異步IO及Epoll模型,採用Tornado的能夠支持數以萬計的併發鏈接,對於高併發的應用有着很好的性能。使用Tornado來運行Flask應用很簡單,只要編寫下面的運行程序,並執行它便可:

from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from myapp import create_app
import config
 
app = create_app('config')
 
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()

以後你就能夠經過」http://example1.com:5000″來訪問應用了

使用Gunicorn運行Flask應用

Gunicorn是一個Python的WSGI Web應用服務器,是從Ruby的Unicorn移植過來的。它基於」pre-fork worker」模型,即預先開啓大量的進程,等待並處理收到的請求,每一個單獨的進程能夠同時處理各自的請求,又避免進程啓動及銷燬的開銷。不過Gunicorn是基於阻塞式IO,併發性能沒法同Tornado比。另外,Gunicorn同uWSGI同樣,通常都是配合着Nginx等Web服務器一同使用。

讓咱們先將應用安裝到遠程服務器上,而後採用Gunicorn啓動應用,使用下面的命令便可:

gunicorn run:app

解釋下,由於咱們的應用使用了工廠方法,因此只在run.py文件中建立了應用對象app,gunicorn命令的參數必須是應用對象,因此這裏是」run:app」。如今你就能夠經過」http://example1.com:8000″來訪問應用了。默認監聽端口是8000。

假設咱們想預先開啓4個工做進程,並監聽本地的5000端口,咱們能夠將啓動命令改成:

gunicorn -w 4 -b 127.0.0.1:5000 run:app
相關文章
相關標籤/搜索