使用 FastCGI 的 Trac
FastCGI 接口允许 Trac 像使用 mod_python 或 mod_wsgi 一样保持常驻。它比外部 CGI 接口更快,外部 CGI 接口必须为每个请求启动一个新进程。此外,它还受到更广泛的 Web 服务器的支持。
请注意,与 mod_python 不同,FastCGI 支持 Apache SuEXEC,即以与 Web 服务器运行权限不同的权限运行。mod_wsgi
支持带有用户/组参数的 WSGIDaemonProcess
以达到相同的效果。
Windows 注意:Trac 的 FastCGI 不在 Windows 上运行,因为 Windows 未实现 Socket.fromfd
,而 _fcgi.py
中使用了它。如果您想连接到 IIS,您可能需要尝试 AJP/ISAPI。
Apache 配置
Apache 通常提供两种 FastCGI 模块:mod_fastcgi
和 mod_fcgid
(首选)。后者更新。
以下部分重点介绍 FCGI 的特定设置,另请参阅 TracModWSGI 以配置 Apache 中的身份验证。
无论使用哪个 CGI 模块,请确保 Web 服务器对 cgi-bin 文件夹具有执行权限。FastCGI 会抛出特定的权限错误,而如果未完成此操作,mod_fcgid 会抛出一个模糊的错误:Connection reset by peer: mod_fcgid: error reading data from FastCGI server
。
使用 mod_fastcgi
设置
mod_fastcgi
使用 FastCgiIpcDir
和 FastCgiConfig
指令,应将其添加到相应的 Apache 配置文件中
# Enable fastcgi for .fcgi files # (If you're using a distro package for mod_fcgi, something like # this is probably already present) <IfModule mod_fastcgi.c> AddHandler fastcgi-script .fcgi FastCgiIpcDir /var/lib/apache2/fastcgi </IfModule> LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so
如果默认值合适,设置 FastCgiIpcDir
是可选的。请注意,LoadModule
行必须在 IfModule
组之后。
按照 TracCgi 中的描述配置 ScriptAlias
或类似选项,但调用 trac.fcgi
而非 trac.cgi
。
如果您打算将 TRAC_ENV
设置为全局默认值,请将以下内容添加到 Apache 配置文件中(FastCgiIpcDir
行下方)
FastCgiConfig -initial-env TRAC_ENV=/path/to/env/trac
或者,您可以通过添加以下内容在目录中提供多个 Trac 项目
FastCgiConfig -initial-env TRAC_ENV_PARENT_DIR=/parent/dir/of/projects
您还可以使用第二个 -initial-env
指令指定 PYTHON_EGG_CACHE
环境变量
FastCgiConfig -initial-env TRAC_ENV=/var/lib/trac \
-initial-env PYTHON_EGG_CACHE=/var/lib/trac/plugin-cache
使用 mod_fcgid
设置
配置 ScriptAlias
(详见 TracCgi),但调用 trac.fcgi
而非 trac.cgi
ScriptAlias /trac /path/to/www/trac/cgi-bin/trac.fcgi/
请注意末尾的斜杠。
要为 mod_fcgid
设置 Trac 环境,需要使用 DefaultInitEnv
指令。它不能在 Directory
或 Location
上下文中使用,因此如果您需要支持多个项目,请尝试下面的替代环境设置
DefaultInitEnv TRAC_ENV /path/to/env/trac/
替代环境设置
指定 Trac 环境路径的更好方法是将路径嵌入到 trac.fcgi
脚本本身中。这不需要配置服务器环境变量,并且适用于 FastCgi 模块以及 lighttpd 和 CGI
import os os.environ['TRAC_ENV'] = "/path/to/projectenv"
或
import os os.environ['TRAC_ENV_PARENT_DIR'] = "/path/to/project/parent/dir"
使用此方法,可以通过使用具有不同 ScriptAliases
的不同 .fcgi
脚本来支持不同的项目。
请参阅 此 fcgid 示例配置,其中 ScriptAlias
指令与 trac.fcgi
一起使用,并带有一个尾部斜杠,如下所示
ScriptAlias / /srv/tracsite/cgi-bin/trac.fcgi/
Cherokee 配置
使用 Trac 配置 Cherokee 非常简单,如果您将 Trac 作为 SCGI 进程启动。您可以手动启动它,或者更好的是,让 Cherokee 在服务器关闭时自动启动它。
首先在 cherokee-admin 中使用本地解释器设置信息源
Host: localhost:4433 Interpreter: /usr/bin/tracd —single-env —daemonize —protocol=scgi —hostname=localhost —port=4433 /path/to/project/
如果端口无法访问,将启动解释器命令。请注意,在信息源的定义中,如果您使用远程主机作为信息源而不是本地解释器,则必须手动启动生成器。
完成此操作后,我们只需创建一个由 SCGI 处理器管理的新规则来访问 Trac。它可以在一个新的虚拟服务器中创建,例如 trac.example.net,并且只需要两条规则。默认规则将使用与先前创建的信息源关联的 SCGI 处理器。第二条规则将用于提供正确显示 Trac 界面所需的少量静态文件。将其创建为 /common 的目录规则,并将其设置为静态文件处理器,文档根目录指向相应的文件:$TRAC_LOCAL/htdocs/(其中 $TRAC_LOCAL 是用户或系统管理员定义的用于放置本地 Trac 资源的目录)。
注意:如果 tracd 进程未能启动,并且 Cherokee 显示 503 错误页面,您可能缺少 python-flup 软件包(#9903)。Python-flup 是一个依赖项,它为 Trac 提供了 SCGI 功能。您可以在基于 Debian 的系统上通过以下方式安装它:
sudo apt-get install python-flup
Lighttpd 配置
FastCGI 前端主要用于与替代 Web 服务器配合使用,例如 Lighttpd。
Lighttpd 是一个安全、快速、兼容且非常灵活的 Web 服务器,已针对高性能环境进行了优化。与其他 Web 服务器相比,它的内存占用非常低,并能处理 CPU 负载。
要将 trac.fcgi
(0.11 之前)/ fcgi_frontend.py(0.11)与 Lighttpd 配合使用,请将以下内容添加到您的 lighttpd.conf 中
#var.fcgi_binary="/usr/bin/python /path/to/fcgi_frontend.py" # 0.11 if installed with easy_setup, it is inside the egg directory var.fcgi_binary="/path/to/cgi-bin/trac.fcgi" # 0.10 name of prior fcgi executable fastcgi.server = ("/trac" => ("trac" => ("socket" => "/tmp/trac-fastcgi.sock", "bin-path" => fcgi_binary, "check-local" => "disable", "bin-environment" => ("TRAC_ENV" => "/path/to/projenv") ) ) )
请注意,您需要为要运行的每个单独的 Trac 实例向 fastcgi.server
添加一个新条目。或者,您可以如上所述使用 TRAC_ENV_PARENT_DIR
变量而不是 TRAC_ENV
,并且您可以将其中一个设置在 trac.fcgi
中,而不是在 lighttpd.conf
中使用 bin-environment
,如上文 Apache 配置部分所述。
请注意,当本例中 fastcgi.server 的 URI 是 '/' 而非 '/trac' 时,Lighttpd 存在一个与 'SCRIPT_NAME' 和 'PATH_INFO' 相关的错误(参见 #2418)。此问题已在 Lighttpd 1.5 中修复,在 Lighttpd 1.4.23 或更高版本中,解决方法是添加 "fix-root-scriptname" => "enable"
作为 fastcgi.server 的参数。
要将两个项目与 lighttpd 配合使用,请将以下内容添加到您的 lighttpd.conf
中
fastcgi.server = ("/first" => ("first" => ("socket" => "/tmp/trac-fastcgi-first.sock", "bin-path" => fcgi_binary, "check-local" => "disable", "bin-environment" => ("TRAC_ENV" => "/path/to/projenv-first") ) ), "/second" => ("second" => ("socket" => "/tmp/trac-fastcgi-second.sock", "bin-path" => fcgi_binary, "check-local" => "disable", "bin-environment" => ("TRAC_ENV" => "/path/to/projenv-second") ) ) )
请注意,字段值是不同的。如果您倾向于在 .fcgi
脚本中设置环境变量,则复制/重命名 trac.fcgi
,例如重命名为 first.fcgi
和 second.fcgi
,并在上述设置中引用它们。请注意,即使两者都从同一个 trac.fcgi
脚本运行,上述操作也将在任何情况下导致不同的进程。
注意:加载 server.modules
的顺序非常重要:如果 mod_auth
未在 mod_fastcgi
之前加载,则服务器将无法验证用户。
对于身份验证,您应该在 lighttpd.conf 的 'server.modules' 中启用 mod_auth
,选择 auth.backend
和 auth
规则
server.modules = ( ... "mod_auth", ... ) auth.backend = "htpasswd" # Separated password files for each project # See "Conditional Configuration" in # https://redmine.lighttpd.ac.cn/projects/lighttpd/repository/entry/doc/configuration.txt?rev=lighttpd-1.4.28 $HTTP["url"] =~ "^/first/" { auth.backend.htpasswd.userfile = "/path/to/projenv-first/htpasswd.htaccess" } $HTTP["url"] =~ "^/second/" { auth.backend.htpasswd.userfile = "/path/to/projenv-second/htpasswd.htaccess" } # Enable auth on trac URLs, see # https://redmine.lighttpd.ac.cn/projects/lighttpd/repository/entry/doc/authentication.txt?rev=lighttpd-1.4.28 auth.require = ("/first/login" => ("method" => "basic", "realm" => "First project", "require" => "valid-user" ), "/second/login" => ("method" => "basic", "realm" => "Second project", "require" => "valid-user" ) )
请注意,如果密码文件不存在,Lighttpd (v1.4.3) 将停止运行。
请注意,Lighttpd 在 1.3.16 之前的版本中不支持 'valid-user'。
条件配置对于映射静态资源也很有用,即直接提供图像和 CSS,而不是通过 FastCGI
# Aliasing functionality is needed server.modules += ("mod_alias") # Set up an alias for the static resources alias.url = ("/trac/chrome/common" => "/usr/share/trac/htdocs") # Use negative lookahead, matching all requests that ask for any resource under /trac, EXCEPT in # /trac/chrome/common, and use FastCGI for those $HTTP["url"] =~ "^/trac(?!/chrome/common)" { # Even if you have other fastcgi.server declarations for applications other than Trac, do NOT use += here fastcgi.server = ("/trac" => ("trac" => ("socket" => "/tmp/trac-fastcgi.sock", "bin-path" => fcgi_binary, "check-local" => "disable", "bin-environment" => ("TRAC_ENV" => "/path/to/projenv") ) ) ) }
通过为每个项目创建别名,并将 fastcgi.server 声明封装在条件配置块中,该技术可以轻松适用于多个项目。
还有另一种处理多个项目的方法,它使用 TRAC_ENV_PARENT_DIR
而非 TRAC_ENV
,以及全局身份验证
# This is for handling multiple projects alias.url = ( "/trac/" => "/path/to/trac/htdocs/" ) fastcgi.server += ("/projects" => ("trac" => ( "socket" => "/tmp/trac.sock", "bin-path" => fcgi_binary, "check-local" => "disable", "bin-environment" => ("TRAC_ENV_PARENT_DIR" => "/path/to/parent/dir/of/projects/" ) ) ) ) #And here starts the global auth configuration auth.backend = "htpasswd" auth.backend.htpasswd.userfile = "/path/to/unique/htpassword/file/trac.htpasswd" $HTTP["url"] =~ "^/projects/.*/login$" { auth.require = ("/" => ( "method" => "basic", "realm" => "trac", "require" => "valid-user" ) ) }
通过环境变量 LC_TIME
,Lighttpd 也支持更改日期/时间格式
fastcgi.server = ("/trac" => ("trac" => ("socket" => "/tmp/trac-fastcgi.sock", "bin-path" => fcgi_binary, "check-local" => "disable", "bin-environment" => ("TRAC_ENV" => "/path/to/projenv", "LC_TIME" => "ru_RU") ) ) )
有关语言规范的详细信息,请参阅 TracFaq 问题 2.13。
其他重要信息,例如映射静态资源的建议,对于非 FastCGI 特定的安装方面也很有用。
重新启动 Lighttpd 并浏览到 http://yourhost.example.org/trac
以访问 Trac。
关于使用受限权限运行 Lighttpd 的注意事项:如果其他方法都无效,并且 trac.fcgi
未在 Lighttpd 设置 server.username = "www-data"
, server.groupname = "www-data"
下启动,则在 bin-environment
部分将 PYTHON_EGG_CACHE
设置为 www-data
的主目录或该帐户可写入的其他目录。
LiteSpeed 配置
FastCGI 前端主要用于与替代 Web 服务器(例如 LiteSpeed)配合使用。
LiteSpeed Web 服务器是一个事件驱动的异步 Apache 替代品,从头开始设计,旨在安全、可扩展并以最少的资源运行。LiteSpeed 可以直接从 Apache 配置文件运行,并针对业务关键型环境。
- 请确保您已成功安装 Trac 项目。首先使用 "tracd" 测试安装。
- 为此设置创建一个虚拟主机。从现在起,我们将此虚拟主机称为 TracVhost。在本教程中,我们将假设您的 Trac 项目可以通过以下方式访问
http://yourdomain.com/trac/
- 转到 "TracVhost → 外部应用" 选项卡并创建一个新的 "外部应用"
Name: MyTracFCGI Address: uds://tmp/lshttpd/mytracfcgi.sock Max Connections: 10 Environment: TRAC_ENV=/fullpathto/mytracproject/ <--- path to root folder of trac project Initial Request Timeout (secs): 30 Retry Timeout (secs): 0 Persistent Connection Yes Connection Keepalive Timeout: 30 Response Bufferring: No Auto Start: Yes Command: /usr/share/trac/cgi-bin/trac.fcgi <--- path to trac.fcgi Back Log: 50 Instances: 10
- 可选:如果您需要使用基于 htpasswd 的身份验证。转到 "TracVhost → 安全" 选项卡并创建一个新的安全域
DB Type: Password File Realm Name: MyTracUserDB <--- any name you wish and referenced later User DB Location: /fullpathto/htpasswd <--- path to your htpasswd file
如果您没有 htpasswd 文件或不知道如何在其中创建条目,请访问 http://sherylcanter.com/encrypt.php,生成用户:密码组合。 - 转到 "PythonVhost → 上下文" 并创建一个新的 FCGI 上下文
URI: /trac/ <--- URI path to bind to python fcgi app we created Fast CGI App: [VHost Level] MyTractFCGI <--- select the Trac fcgi extapp we just created Realm: TracUserDB <--- only if (4) is set. select realm created in (4)
- 修改
/fullpathto/mytracproject/conf/trac.ini
#find/set base_rul, url, and link variables base_url = http://yourdomain.com/trac/ <--- base url to generate correct links to url = http://yourdomain.com/trac/ <--- link of project link = http://yourdomain.com/trac/ <--- link of graphic logo
- 重启 LiteSpeed:
lswsctrl restart
,然后通过http://yourdomain.com/trac/
访问您的新 Trac 项目。
Nginx 配置
Nginx 能够与 FastCGI 进程通信,但无法生成它们。因此,您需要单独启动 Trac 的 FastCGI 服务器。
- 使用 Nginx 处理基本身份验证的 Nginx 配置 - 确认在 0.6.32 上可用
server { listen 10.9.8.7:443; server_name trac.example; ssl on; ssl_certificate /etc/ssl/trac.example.crt; ssl_certificate_key /etc/ssl/trac.example.key; ssl_session_timeout 5m; ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; # it makes sense to serve static resources through Nginx (or ``~ [/some/prefix]/chrome/(.*)``) location ~ /chrome/(.*) { alias /home/trac/instance/static/htdocs/$1; } # You can copy this whole location to ``location [/some/prefix](/login)`` # and remove the auth entries below if you want Trac to enforce # authorization where appropriate instead of needing to authenticate # for accessing the whole site. # (Or ``~ location /some/prefix(/.*)``.) location ~ (/.*) { auth_basic "trac realm"; auth_basic_user_file /home/trac/htpasswd; # socket address fastcgi_pass unix:/home/trac/run/instance.sock; # python - wsgi specific fastcgi_param HTTPS on; ## WSGI REQUIRED VARIABLES # WSGI application name - trac instance prefix. # (Or ``fastcgi_param SCRIPT_NAME /some/prefix``.) fastcgi_param SCRIPT_NAME ""; fastcgi_param PATH_INFO $1; ## WSGI NEEDED VARIABLES - trac warns about them fastcgi_param REQUEST_METHOD $request_method; fastcgi_param SERVER_NAME $server_name; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param QUERY_STRING $query_string; # For Nginx authentication to work - do not forget to comment these # lines if not using Nginx for authentication fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; # for ip to work fastcgi_param REMOTE_ADDR $remote_addr; # For attchments to work fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; } }
- 修改后的 trac.fcgi
#!/usr/bin/env python import os sockaddr = '/home/trac/run/instance.sock' os.environ['TRAC_ENV'] = '/home/trac/instance' try: from trac.web.main import dispatch_request import trac.web._fcgi fcgiserv = trac.web._fcgi.WSGIServer(dispatch_request, bindAddress = sockaddr, umask = 7) fcgiserv.run() except SystemExit: raise except Exception, e: print 'Content-Type: text/plain\r\n\r\n', print 'Oops...' print print 'Trac detected an internal error:' print print e print import traceback import StringIO tb = StringIO.StringIO() traceback.print_exc(file=tb) print tb.getvalue()
- 重新加载 nginx 并启动 trac.fcgi
trac@trac.example ~ $ ./trac-standalone-fcgi.py
上述假设
- 有一个名为 'trac' 的用户,用于运行 Trac 实例并在其主目录中保存 Trac 环境
/home/trac/instance
包含一个 Trac 环境/home/trac/htpasswd
包含身份验证信息/home/trac/run
属于 Nginx 运行的用户组- 如果您的系统是 Linux,则
/home/trac/run
设置了 setgid 位(chmod g+s run
) - 并且已应用 #7239 的补丁,否则您每次都必须修复套接字文件权限
- 如果您的系统是 Linux,则
不幸的是,Nginx 不支持 fastcgi_pass
指令中的变量扩展。因此,无法从一个服务器块提供多个 Trac 实例。
如果您足够关注安全性,请在单独的用户下运行 Trac 实例。
在 #6224 中提供了另一种将 Trac 作为 FCGI 外部应用程序运行的方法。