FastCGI ¶
FastCGI是在nginx,lighttpd和cherokee等服务器上的部署选项;有关其他选项,请参阅uWSGI和Standalone WSGI Containers。 在它们上的任何一个运行你的 WSGI 应用首先需要一个 FastCGI 服务器。 最受欢迎的是flup,我们将在本指南中使用它。 确保你已经安装好它来跟随下面的说明。
小心
请提前确保你在应用文件中的任何 app.run()
调用在 if __name__ == '__main__':
块中或是移到一个独立的文件。 这是因为它总会启动一个本地 的 WSGI 服务器,并且我们在部署应用到 uWSGI 时不需要它。
创建.fcgi文件¶
首先你需要创建一个 FastCGI 服务器文件。 让我们把它叫做 yourapplication.fcgi:
#!/usr/bin/python
from flup.server.fcgi import WSGIServer
from yourapplication import app
if __name__ == '__main__':
WSGIServer(app).run()
这已经可以为 Apache 工作,而 nginx 和老版本的 lighttpd 需要传递一个 显式的 socket 来与 FastCGI 通信。 为此,你需要传递 socket 的路径到 WSGIServer
:
WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()
这个路径一定与你在服务器配置中定义的路径相同。
将yourapplication.fcgi
文件保存到某处,您将再次找到它。在/var/www/yourapplication
或类似的东西是有意义的。
确保这个文件有执行权限,这样服务器才能执行它:
# chmod +x /var/www/yourapplication/yourapplication.fcgi
配置Apache ¶
上面的示例对于基本的Apache部署是足够好的,但是您的.fcgi文件将会出现在您的应用程序网址中。 example.com/yourapplication.fcgi/news/
。 在这种情况下,错误看起来是“yourapplication”不在 python 路径下。 一个给 lighttpd 的基本的 FastCGI 配置看起来是这样: 以下示例使用FastCgiServer启动将处理所有传入请求的应用程序的5个实例:
LoadModule fastcgi_module /usr/lib64/httpd/modules/mod_fastcgi.so
FastCgiServer /var/www/html/yourapplication/app.fcgi -idle-timeout 300 -processes 5
<VirtualHost *>
ServerName webapp1.mydomain.com
DocumentRoot /var/www/html/yourapplication
AddHandler fastcgi-script fcgi
ScriptAlias / /var/www/html/yourapplication/app.fcgi/
<Location />
SetHandler fastcgi-script
</Location>
</VirtualHost>
这些进程将由Apache管理。 在 nginx 上安装 FastCGI 应用有一点不同,因为默认没有 FastCGI 参数被转 发。 注意,在下面的路径不是真的,它只是用作其他指令的标识符,如AliasMatch:
FastCgiServer /var/www/html/yourapplication -host 127.0.0.1:3000
如果无法设置ScriptAlias,例如在共享Web主机上,可以使用WSGI中间件从URL中删除yourapplication.fcgi。设置.htaccess:
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi
<Files ~ (\.fcgi)>
SetHandler fcgid-script
Options +FollowSymLinks +ExecCGI
</Files>
</IfModule>
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ yourapplication.fcgi/$1 [QSA,L]
</IfModule>
设置yourapplication.fcgi:
#!/usr/bin/python
#: optional path to your local python site-packages folder
import sys
sys.path.insert(0, '<your_local_path>/lib/python2.6/site-packages')
from flup.server.fcgi import WSGIServer
from yourapplication import app
class ScriptNameStripper(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return self.app(environ, start_response)
app = ScriptNameStripper(app)
if __name__ == '__main__':
WSGIServer(app).run()
配置lighttpd ¶
一个给 nginx 的基本的 FastCGI 配置看起来是这样:
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 ,别名和重写模块。 此配置将应用程序绑定到/yourapplication
。 如果想要应用运行在 URL 根路径,你需要用 LighttpdCGIRootFix
中间件来处理 一个 lighttpd 的 bug 。
确保只在应用挂载到 URL 根路径时才应用它。 此外,有关FastCGI和Python的更多信息,请参阅Lighty文档(注意,不再需要将套接字显式传递给run())。
配置nginx ¶
既然 Nginx 和其它服务器并不加载 FastCGI 应用,你需要手动这么做。
nginx的基本Flask FastCGI配置如下所示:
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;
}
此配置将应用程序绑定到/yourapplication
。如果您希望在网址根中包含它,它会更简单一些,因为您不必弄明白如何计算PATH_INFO
和SCRIPT_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;
}
运行FastCGI进程¶
由于nginx和其他人不加载FastCGI应用程序,你必须自己做。 Supervisor 可以管理 FastCGI 进程。 你可以寻找其它 FastCGI 进程管理器或写一个启动时运行 .fcgi 文件的脚本, 例如使用一个 SysV init.d
脚本。 对于临时的解决方案,你总是可以在 GNU screen 中运行 .fcgi
。 更多细节见 man screen
,注意这是一个手动 的解决方案,并且不会在系统重启后保留:
$ screen
$ /var/www/yourapplication/yourapplication.fcgi
调试¶
FastCGI 在大多数 web 服务器上的部署,对于调试趋于复杂。 服务器日志最经常 告诉发生的事就是成行的“未预期的标头结尾”。 为了调试应用,唯一可以让你了解 什么东西破碎的方案就是切换到正确的用户并手动执行应用。
这个例子假设你的应用叫做 application.fcgi 并且你的 web 服务器用户是 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
在这种情况下,错误似乎是“yourapplication”不在python路径。 常见的 问题是:
- 使用了相对路径。 不要依赖于当前工作目录
- 代码依赖于不是从 web 服务器设置的环境变量
- 使用了不同的 python 解释器