我採用的部署方案是:
Web 服務器採用 uwsgi host Flask
用 Supervisor 引用 uwsgi 作常規啓動服務
基於 Nginx 作反向代理
首先, 阿里雲服務器可以通過 SSH 指令在本機的終端進行遠程連接
ssh root@雲服務器地址
輸入密碼進入後所有的操作與本地終端完全一至。
安裝 Python 環境
接下來是python , Ubuntu 的默認環境已經預裝 python 2.7 所以只需要安裝 python 的 pip 安裝工具即可。pip 用於安裝一些基於python 應用的軟件工具,在下文中將會頻繁使用。
PIP
如果用python 指令如下:
sudo apt-get install pip
VirtualEnv
不同的項目可能會引用各種不同的依賴包,爲了避免版本與和應用之間的衝突而造成的“依賴地獄”
[Virtualenv | https://virtualenv.readthedocs.org/en/latest/] 就是我們python 項目的必須品了。VirtualEnv 可以爲每個Python應用創建獨立的開發環境,使他們互不影響,Virtualenv 能夠做到:
在沒有權限的情況下安裝新套件
不同應用可以使用不同的套件版本
套件升級不影響其他應用
安裝:
sudo pip install virtualenv
安裝VirtualEnv 後只需要在項目目錄內運行 virtualenv 目錄名 就可以建立一個虛擬環境文件夾,然後啓用 activate 指令即可啓用該python虛擬環境,具體操作如下:
假定我的項目目錄叫 /home/www/my_flask,首先安裝虛擬環境 (我習慣使用的虛擬環境目錄叫 venv )
my_flask root$ virtualenv venv
New python executable in venv/bin/python
Installing setuptools, pip...done.
在項目目錄下就會建立一個新的 venv 目錄,裏面就是運行python 的基本環境的工具與指令,和包。 然後啓用該環境,使用當前命令行狀態進入虛擬環境,進入虛擬環境後,一切安裝python的操作都會將包和引用裝在虛擬環境內,而不會影響到全局的python 環境。
my_flask root$ source venv/bin/activate
(venv)my_flask root$
調用 activate 指令後命令符前就會出現 (venv) 字樣。 可通過 deactivate 退出虛擬環境。
安裝 uWSGI
我現採用的是 uWSGI。接下來就安裝uWSGI吧。
(venv)my_flask root$ pip install uwsgi
在虛擬環境下不需要使用 sudo ,因爲virtualenv 是沒有權限要求的。
這個安裝很迅速,基本是秒成。安裝完成後我們可以先放下 uWSGI 不表,在後面再回過來配置他,因爲我們首先要將關鍵的 Flask環境和我們的項目文件傳到服務器目錄內。
安裝 Flask
我是用清單文件一次性安裝Flask和他的相關依賴的,這樣會更快。我的引用清單是這樣的:
requirements.txt
Flask==0.10.1
Flask-Login==0.2.11
Flask-Mail==0.9.1
Flask-Moment==0.4.0
Flask-PageDown==0.1.5
Flask-SQLAlchemy==2.0
Flask-Script==2.0.5
Flask-WTF==0.10.2
Flask-Cache==0.13.1
Flask-Restless==0.15.0
Flask-Uploads==0.1.3
Jinja2==2.7.3
Mako==1.0.0
Markdown==2.5.1
MarkupSafe==0.23
SQLAlchemy==0.9.8
WTForms==2.0.1
Werkzeug==0.9.6
html5lib==1.0b3
itsdangerous==0.24
six==1.8.0
awesome-slugify==1.6
可以想像,如果一個一個裝非瘋了不可。
安裝清單文件:
(venv)my_flask root$ pip install -r requirements.txt
在此還是重重地提一下:一定要注意在運行這個安裝之前啓用了python 虛擬環境,否則會直接安裝到全局去的!
項目文件
接下來就是上傳 Flask的項目文件,之前我在各大的“轉載專業戶”裏找了好多的資料,在這一步中大多只是在上面加個標準的Flask運行文件,雖說做個範例可以但說實在的這很讓人迷惑,爲什麼?先看看代碼吧:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
生產環境內,誰會用這樣的代碼呢,這只是Flask 的最簡入門範,我的Flask項目中 app 是被做在包內的,相信很多人都是這樣做的,在包外我們採用 Flask Script 寫一個 manage.py 文件 作爲啓動文件,這更方便於支持各種的項目,包括可以安裝到 window下的 FastCGI 中。
那麼我的 這個 manage.py 是這個樣子的:
!/usr/bin/env python
import os
if os.path.exists('.env'):
print('Importing environment from .env...')
for line in open('.env'):
var = line.strip().split('=')
if len(var) == 2:
os.environ[var[0]] = var[1]
from app import create_app
from flask.ext.script import Manager, Shell
通過配置創建 app
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
def make_shell_context():
return dict(app=app)
manager.add_command("shell", Shell(make_context=make_shell_context))
@manager.command
def deploy():
"""Run deployment tasks."""
pass
if name == '__main__':
manager.run()
這樣做我地開發環境可以這樣運行 Flask:
python manage.py runserver
好吧,我們可以用 支持SSH的FTP工具將Flask項目文件上傳到服務器上,下面是整個項目文件結構:
www/
└── my_flask
│ ├── logs
│ └── venv //虛擬目錄
│ │ ├── bin
│ │ │ ├── activate
│ │ │ ├── easy_install
│ │ │ ├── gunicorn
│ │ │ ├── pip
│ │ │ └── python
│ │ ├── include
│ │ │ └── python2.7 -> /usr/include/python2.7
│ │ ├── lib
│ │ │ └── python2.7
│ │ ├── local
│ │ │ ├── bin -> /home/shenye/shenyefuli/bin
│ │ │ ├── include -> /home/shenye/shenyefuli/include
│ │ │ └── lib -> /home/shenye/shenyefuli/lib
│ └── app //Flask 程序目錄
│ │ └── __init__.py //這是程序包文件。這個目錄下還有其它的文件此處略過
│ ├── manage.py
│ ├── requirements.txt
配置 uwsgi
好了,項目的準備工作已經做完了,是時候回過頭去配置 uwsgi 了,它的具體指令可以去看它的官方文檔,我們在這裏採用其中的一種指令方式:配置起動。我採用 .ini文件作爲配置,在項目目錄下創建一個 confg.ini (具體見下文)寫好後可以這樣執行
(venv)my_flask root$ uwsgi config.ini
我認爲是最簡單的方式,也容易更改。好了重要部分來了,config.ini 是這樣寫的:
[uwsgi]
uwsgi 啓動時所使用的地址與端口
socket = 127.0.0.1:8001
指向網站目錄
chdir = /home/www/
python 啓動程序文件
wsgi-file = manage.py
python 程序內用以啓動的 application 變量名
callable = app
處理器數
processes = 4
線程數
threads = 2
狀態檢測地址
stats = 127.0.0.1:9191
注意 : callable=app 這個 app 是 manage.py 程序文件內的一個變量,這個變量的類型是 Flask的 application 類 。
運行 uwsgi
(venv)my_flask root$ uwsgi config.ini
[uWSGI] getting INI configuration from config.ini
Starting uWSGI 2.0.8 (64bit) on [Fri Dec 19 14:34:11 2014]
// 此處略去那些無用的啓動信息
Stats server enabled on 127.0.0.1:9191 fd: 15
OK, 此時已經正常啓動 uwsgi 並將 Flask 項目載入其中了,ctrl+c 關閉程序。但這只是命令啓動形式,要使其隨同服務器啓動並作爲後臺服務運行纔是運營環境的實際所需要。因此接下來我們需要安裝另一個工具來引導 uwsgi 。
安裝 Supervisor
可以同時啓動多個應用,最重要的是,當某個應用Crash的時候,他可以自動重啓該應用,保證可用性。
sudo apt-get install supervisor
Supervisor 的全局的配置文件位置在:
/etc/supervisor/supervisor.conf
正常情況下我們並不需要去對其作出任何的改動,只需要添加一個新的 *.conf 文件放在
/etc/supervisor/conf.d/
下就可以,那麼我們就新建立一個用於啓動 my_flask 項目的 uwsgi 的 supervisor 配置 (命名爲:my_flask_supervisor.conf):
[program:my_flask]
啓動命令入口
command=/home/www/my_flask/venv/bin/uwsgi /home/www/my_flask/config.ini
命令程序所在目錄
directory=/home/www/my_flask
運行命令的用戶名
user=root
autostart=true
autorestart=true
日誌地址
stdout_logfile=/home/www/my_flask/logs/uwsgi_supervisor.log
啓動服務
sudo service supervisor start
終止服務
sudo service supervisor stop
安裝 Nginx
sudo apt-get install nginx
配置 Nginx
Ubuntu 上配置 Nginx 也是很簡單,不要去改動默認的 nginx.conf 只需要將
/ext/nginx/sites-available/default
文件替換掉就可以了。
新建一個 default 文件:
server {
listen 80;
server_name XXX.XXX.XXX; #公網地址
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8001; # 指向uwsgi 所應用的內部地址,所有請求將轉發給uwsgi 處理
uwsgi_param UWSGI_PYHOME /home/www/my_flask/venv; # 指向虛擬環境目錄
uwsgi_param UWSGI_CHDIR /home/www/my_flask; # 指向網站根目錄
uwsgi_param UWSGI_SCRIPT manage:app; # 指定啓動程序
}
}
將default配置文件替換掉就大功告成了!
還有,更改配置還需要記得重啓一下nginx:
sudo service nginx restart