VirtualBox

使用 FastCGI 的 Trac

FastCGI 接口允许 Trac 像使用 mod_pythonmod_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_fastcgimod_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 使用 FastCgiIpcDirFastCgiConfig 指令,应将其添加到相应的 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 指令。它不能在 DirectoryLocation 上下文中使用,因此如果您需要支持多个项目,请尝试下面的替代环境设置

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.fcgisecond.fcgi,并在上述设置中引用它们。请注意,即使两者都从同一个 trac.fcgi 脚本运行,上述操作也将在任何情况下导致不同的进程。

注意:加载 server.modules 的顺序非常重要:如果 mod_auth 未在 mod_fastcgi 之前加载,则服务器将无法验证用户。

对于身份验证,您应该在 lighttpd.conf 的 'server.modules' 中启用 mod_auth,选择 auth.backendauth 规则

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 配置文件运行,并针对业务关键型环境。

  1. 请确保您已成功安装 Trac 项目。首先使用 "tracd" 测试安装。
  2. 为此设置创建一个虚拟主机。从现在起,我们将此虚拟主机称为 TracVhost。在本教程中,我们将假设您的 Trac 项目可以通过以下方式访问
    http://yourdomain.com/trac/
    
  3. 转到 "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
    
  4. 可选:如果您需要使用基于 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,生成用户:密码组合。
  5. 转到 "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)
    
  6. 修改 /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
    
  7. 重启 LiteSpeed:lswsctrl restart,然后通过 http://yourdomain.com/trac/ 访问您的新 Trac 项目。

Nginx 配置

Nginx 能够与 FastCGI 进程通信,但无法生成它们。因此,您需要单独启动 Trac 的 FastCGI 服务器。

  1. 使用 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;
            }
        }
    
  2. 修改后的 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()
    
    
  3. 重新加载 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 的补丁,否则您每次都必须修复套接字文件权限

不幸的是,Nginx 不支持 fastcgi_pass 指令中的变量扩展。因此,无法从一个服务器块提供多个 Trac 实例。

如果您足够关注安全性,请在单独的用户下运行 Trac 实例。

#6224 中提供了另一种将 Trac 作为 FCGI 外部应用程序运行的方法。


另请参阅:Trac指南Trac安装ModWSGICGIModPythonTracNginxRecipe

上次修改 2 年前 最后修改于 2023年06月02日 10:32:55 AM
注意: 查看 TracWiki 获取使用维基的帮助。

© 2025 Oracle 支持 隐私 / 请勿出售我的信息 使用条款 商标政策 自动化访问礼仪