使用 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 外部应用程序运行的方法。

