Flask FastCGI

2021-08-11 10:51 更新

FastCGI 是在像 nginx 、 lighttpdcherokee 服務(wù)器上的一個(gè)部署選擇。 其它選擇見 uWSGI 獨(dú)立 WSGI 容器 章節(jié)。 在它們上的任何一個(gè)運(yùn)行你的 WSGI 應(yīng)用首先需要一個(gè) FastCGI 服務(wù)器。最流行的一個(gè) 是 flup ,我們會(huì)在本指導(dǎo)中使用它。確保你已經(jīng)安裝好它來(lái)跟隨下面的說(shuō)明。

注意

請(qǐng)?zhí)崆按_保你在應(yīng)用文件中的任何 app.run() 調(diào)用在 if __name__ == '__main__': 塊中或是移到一個(gè)獨(dú)立的文件。這是因?yàn)樗倳?huì)啟動(dòng)一個(gè)本地 的 WSGI 服務(wù)器,并且我們?cè)诓渴饝?yīng)用到 uWSGI 時(shí)不需要它。

創(chuàng)建一個(gè) .fcgi 文件

首先你需要?jiǎng)?chuàng)建一個(gè) FastCGI 服務(wù)器文件。讓我們把它叫做 yourapplication.fcgi:

#!/usr/bin/python
from flup.server.fcgi import WSGIServer
from yourapplication import app

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

這已經(jīng)可以為 Apache 工作,而 nginx 和老版本的 lighttpd 需要傳遞一個(gè) 顯式的 socket 來(lái)與 FastCGI 通信。為此,你需要傳遞 socket 的路徑到 WSGIServer:

WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()

這個(gè)路徑一定與你在服務(wù)器配置中定義的路徑相同。

yourapplication.fcgi 文件保存到你能找到的地方。保存在 /var/www/yourapplication 或類似的地方是有道理的。

確保這個(gè)文件有執(zhí)行權(quán)限,這樣服務(wù)器才能執(zhí)行它:

# chmod +x /var/www/yourapplication/yourapplication.fcgi

配置 lighttpd

一個(gè)給 lighttpd 的基本的 FastCGI 配置看起來(lái)是這樣:

fastcgi.server = ("/yourapplication.fcgi" =>
    ((
        "socket" => "/tmp/yourapplication-fcgi.sock",
        "bin-path" => "/var/www/yourapplication/yourapplication.fcgi",
        "check-local" => "disable",
        "max-procs" => 1
    ))
)

alias.url = (
    "/static/" => "/path/to/your/static"
)

url.rewrite-once = (
    "^(/static.*)$" => "$1",
    "^(/.*)$" => "/yourapplication.fcgi$1"

記得啟用 FastCGI ,別名和重寫模塊。這份配置把應(yīng)用綁定到 /yourapplication 。如果想要應(yīng)用運(yùn)行在 URL 根路徑,你需要用 LighttpdCGIRootFix 中間件來(lái)處理 一個(gè) lighttpd 的 bug 。

確保只在應(yīng)用掛載到 URL 根路徑時(shí)才應(yīng)用它。同樣,更多信息請(qǐng)翻閱 Lighty 的文檔關(guān)于 FastCGI and Python 的部分(注意顯示傳遞一個(gè) socket 到 run() 不再是必須的)。

配置 nginx

在 nginx 上安裝 FastCGI 應(yīng)用有一點(diǎn)不同,因?yàn)槟J(rèn)沒(méi)有 FastCGI 參數(shù)被轉(zhuǎn) 發(fā)。

一個(gè)給 nginx 的基本的 FastCGI 配置看起來(lái)是這樣:

location = /yourapplication { rewrite ^ /yourapplication/ last; }
location /yourapplication { try_files $uri @yourapplication; }
location @yourapplication {
    include fastcgi_params;
    fastcgi_split_path_info ^(/yourapplication)(.*)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}

這份配置把應(yīng)用綁定到 /yourapplication 。如果你想要綁定到 URL 跟了路徑 會(huì)更簡(jiǎn)單,因?yàn)槟悴恍枰赋鋈绾潍@取 PATH_INFOSCRIPT_NAME:

location / { try_files $uri @yourapplication; }
location @yourapplication {
    include fastcgi_params;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    fastcgi_param SCRIPT_NAME "";
    fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}

運(yùn)行 FastCGI 進(jìn)程

既然 Nginx 和其它服務(wù)器并不加載 FastCGI 應(yīng)用,你需要手動(dòng)這么做。 Supervisor 可以管理 FastCGI 進(jìn)程。 你可以尋找其它 FastCGI 進(jìn)程管理器或?qū)懸粋€(gè)啟動(dòng)時(shí)運(yùn)行 .fcgi 文件的腳本, 例如使用一個(gè) SysV init.d 腳本。對(duì)于臨時(shí)的解決方案,你總是可以在 GNU screen 中運(yùn)行 .fcgi 。更多細(xì)節(jié)見 man screen ,注意這是一個(gè)手動(dòng) 的解決方案,并且不會(huì)在系統(tǒng)重啟后保留:

$ screen
$ /var/www/yourapplication/yourapplication.fcgi

調(diào)試

FastCGI 在大多數(shù) web 服務(wù)器上的部署,對(duì)于調(diào)試趨于復(fù)雜。服務(wù)器日志最經(jīng)常 告訴發(fā)生的事就是成行的“未預(yù)期的標(biāo)頭結(jié)尾”。為了調(diào)試應(yīng)用,唯一可以讓你了解 什么東西破碎的方案就是切換到正確的用戶并手動(dòng)執(zhí)行應(yīng)用。

這個(gè)例子假設(shè)你的應(yīng)用叫做 application.fcgi 并且你的 web 服務(wù)器用戶是 www-data:

$ su www-data
$ cd /var/www/yourapplication
$ python application.fcgi
Traceback (most recent call last):
  File "yourapplication.fcgi", line 4, in <module>
ImportError: No module named yourapplication

在這種情況下,錯(cuò)誤看起來(lái)是“yourapplication”不在 python 路徑下。常見的 問(wèn)題是:

  • 使用了相對(duì)路徑。不要依賴于當(dāng)前工作目錄
  • 代碼依賴于不是從 web 服務(wù)器設(shè)置的環(huán)境變量
  • 使用了不同的 python 解釋器


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)