Trac 和 mod_python
Mod_python 是一个 Apache 模块,它将 Python 解释器嵌入到服务器中,从而使基于 Python 的 Web 应用程序比传统 CGI 运行快很多倍,并能够保持数据库连接。 Trac 支持 mod_python,这显著加快了 Trac 的响应时间,特别是与 CGI 相比,并允许使用许多 tracd/mod_proxy 无法实现的 Apache 功能。
概述
简单配置:单一项目
如果您刚刚安装了 mod_python,可能需要在 Apache 配置中添加一行来加载该模块
LoadModule python_module modules/mod_python.so
注意:模块的确切路径取决于 HTTPD 的安装布局。
在 Debian 上使用 apt-get
apt-get install libapache2-mod-python libapache2-mod-python-doc
仍在 Debian 上,安装 mod_python 后,您必须在 apache2 中启用模块,这等同于上面的 Load Module 指令
a2enmod python
在 Fedora 上使用 yum
yum install mod_python
您可以将以下内容添加到 httpd.conf 中来测试您的 mod_python 安装。出于安全原因,测试完成后应将其删除。注意:mod_python.testhandler 仅在 mod_python 3.2+ 版本中可用。
<Location /mpinfo> SetHandler mod_python PythonInterpreter main_interpreter PythonHandler mod_python.testhandler # For Apache 2.2 <IfModule !mod_authz_core.c> Order allow,deny Allow from all </IfModule> # For Apache 2.4 <IfModule mod_authz_core.c> Require all granted </IfModule> </Location>
Trac 在 mod_python 上的简单设置如下所示
<Location /projects/myproject> SetHandler mod_python PythonInterpreter main_interpreter PythonHandler trac.web.modpython_frontend PythonOption TracEnv /var/trac/myproject PythonOption TracUriRoot /projects/myproject # For Apache 2.2 <IfModule !mod_authz_core.c> Order allow,deny Allow from all </IfModule> # For Apache 2.4 <IfModule mod_authz_core.c> Require all granted </IfModule> </Location>
您的设置中可能需要或不需要 TracUriRoot
选项。请尝试不使用它进行配置;如果 Trac 生成的 URL 看起来不正确,如果 Trac 似乎无法正确识别 URL,或者您收到奇怪的“No handler matched request to...”错误,请添加 TracUriRoot
选项。您会注意到 Location
和 TracUriRoot
具有相同的路径。
可用的选项有
# For a single project PythonOption TracEnv /var/trac/myproject # For multiple projects PythonOption TracEnvParentDir /var/trac/myprojects # For the index of multiple projects PythonOption TracEnvIndexTemplate /srv/www/htdocs/trac/project_list_template.html # A space delimitted list, with a "," between key and value pairs. PythonOption TracTemplateVars key1,val1 key2,val2 # Useful to get the date in the wanted order PythonOption TracLocale en_GB.UTF8 # See description above PythonOption TracUriRoot /projects/myproject
Python Egg 缓存
像 Genshi 这样的压缩 Python egg 文件通常会被解压到用户主目录中一个名为 .python-eggs
的目录中。由于 Apache 的主目录通常不可写,因此可以像这样指定一个备用的 egg 缓存目录
PythonOption PYTHON_EGG_CACHE /var/trac/myprojects/egg-cache
或者您可以解压 Genshi egg 文件以解决从中提取时遇到的问题。
配置身份验证
请参阅 TracModWSGI 页面中的相应部分。
高级配置
设置 Python Egg 缓存
如果 Egg 缓存目录 Web 服务器不可写,您将需要更改权限,或者将 Python 指向 Apache 可写的目录。这可能会表现为 500 内部服务器错误
和/或 syslog 中的抱怨信息。
<Location /projects/myproject> ... PythonOption PYTHON_EGG_CACHE /tmp ... </Location>
设置 PythonPath
如果 Trac 未安装在您的 Python 路径中,您将需要使用 PythonPath
指令告知 Apache 在何处找到 Trac mod_python 处理程序
<Location /projects/myproject> ... PythonPath "sys.path + ['/path/to/trac']" ... </Location>
请注意使用 PythonPath 指令,而不是 SetEnv PYTHONPATH
,因为后者将不起作用。
设置多个项目
Trac mod_python 处理程序支持一个类似于 Subversion 的 SvnParentPath
的配置选项,名为 TracEnvParentDir
<Location /projects> SetHandler mod_python PythonInterpreter main_interpreter PythonHandler trac.web.modpython_frontend PythonOption TracEnvParentDir /var/trac PythonOption TracUriRoot /projects </Location>
当您请求 /projects
URL 时,您将获得您设置为 TracEnvParentDir
的目录中所有看起来像 Trac 环境目录的子目录列表。选择列表中的任何项目都会将您带到相应的 Trac 环境。
位于 TracEnvParentDir
中但不是环境目录的目录将在项目索引页面上显示错误消息。这些目录可以通过将它们列在 TracEnvParentDir
中的 .tracignore
文件中来排除。Unix shell 风格的通配符模式可以在换行符分隔的目录列表中使用。
如果您不想将子目录列表作为您的项目主页,您可以使用
<LocationMatch "/.+/">
这将指示 Apache 对所有非根位置使用 mod_python,同时您可以在 DocumentRoot 文件夹中为根目录放置自定义主页。
您还可以使用 <LocationMatch>
指令为所有项目使用相同的身份验证领域
<LocationMatch "/projects/[^/]+/login"> AuthType Basic AuthName "Trac" AuthUserFile /var/trac/.htpasswd Require valid-user </LocationMatch>
虚拟主机配置
以下是将 Trac 设置为虚拟服务器所需的示例配置,即当您通过诸如 http://trac.mycompany.com
之类的 URL 访问它时
<VirtualHost *> DocumentRoot /var/www/myproject ServerName trac.mycompany.com <Location /> SetHandler mod_python PythonInterpreter main_interpreter PythonHandler trac.web.modpython_frontend PythonOption TracEnv /var/trac/myproject PythonOption TracUriRoot / </Location> <Location /login> AuthType Basic AuthName "MyCompany Trac Server" AuthUserFile /var/trac/myproject/.htpasswd Require valid-user </Location> </VirtualHost>
这并非在所有情况下都有效。如果无效,您可以尝试以下操作
- 尝试使用
<LocationMatch>
而不是<Location>
。 - 在您的服务器设置中,
<Location />
可能指代整个主机,而不是简单地指服务器的根目录。这意味着所有内容(包括下面引用的登录目录)都将被发送到 Python,并且身份验证将不起作用,即您会收到臭名昭著的“身份验证信息丢失”错误。如果出现这种情况,请尝试为 Trac 使用子目录而不是根目录,例如使用 /web/ 和 /web/login,而不是 / 和 /login。 - 根据 Apache 的
NameVirtualHost
配置,您可能需要使用<VirtualHost *:80>
而不是<VirtualHost *>
。
对于支持多个项目的虚拟主机,请将 TracEnv /var/trac/myproject
替换为 TracEnvParentDir /var/trac
。
注意:DocumentRoot 不应指向您的 Trac 项目环境。正如 Asmodai 在 #trac 上所写:“假设存在允许泄露 DocumentRoot 的 Web 服务器错误,他们就可以窃取整个 Trac 环境”。
故障排除
如果出现服务器错误页面,您可以检查 Apache 错误日志,或启用 PythonDebug
选项
<Location /projects/myproject> ... PythonDebug on </Location>
对于多个项目,也请尝试重新启动服务器。
登录不起作用
如果您使用了 <Location />
指令,它将覆盖任何其他指令,以及 <Location /login>
。解决方法是使用如下的否定表达式(适用于多项目设置)
#this one for other pages <Location ~ "/*(?!login)"> SetHandler mod_python PythonHandler trac.web.modpython_frontend PythonOption TracEnvParentDir /projects PythonOption TracUriRoot / </Location> #this one for login page <Location ~ "/[^/]+/login"> SetHandler mod_python PythonHandler trac.web.modpython_frontend PythonOption TracEnvParentDir /projects PythonOption TracUriRoot / #remove these if you don't want to force SSL RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} AuthType Basic AuthName "Trac" AuthUserFile /projects/.htpasswd Require valid-user </Location>
Expat 相关段错误
在 Unix 上使用 Python 2.4 时,您很可能会遇到此问题。在 Python 2.4 中,会使用某个版本的 Expat(一个用 C 编写的 XML 解析库),如果 Apache 使用另一个版本,这会导致段错误。由于 Trac 0.11 使用 Genshi(它将间接使用 Expat),即使 Trac 0.10 之前一切正常,现在您也可能会遇到此问题。Python 2.5+ 版本尚未报告此问题,因此最好升级。
表单提交问题
如果您在 Trac 中提交某些表单时遇到问题(一个常见问题是提交后您会被重定向到起始页面),请检查您的 DocumentRoot
是否包含与您映射 mod_python 处理程序的路径相同的文件夹或文件。由于某种原因,当 mod_python 映射到的位置也与静态资源匹配时,它会感到困惑。
虚拟主机配置问题
如果使用 <Location /> 指令,设置 DocumentRoot
可能会导致 403 (Forbidden) 错误。要么删除 DocumentRoot
指令,要么确保在相应的 <Directory>
块中允许访问其指向的目录。
将 <Location /> 与 SetHandler
一起使用导致所有内容都由 mod_python 处理,从而无法下载任何 CSS 或图像/图标。使用 <Location /trac> SetHandler None
</Location> 可以规避此问题,尽管这可能不是最优雅的解决方案。
压缩蛋文件问题
您的 mod_python 版本可能无法从压缩的 egg 文件中导入模块。如果您在 Apache 日志中遇到 ImportError: No module named trac
,但您认为一切都已就绪,那么这可能就是您的问题。查看您的 site-packages 目录;如果 Trac 模块显示为文件而不是目录,那么这可能就是您的问题。要解决此问题,请尝试使用 --always-unzip
选项安装 Trac
easy_install --always-unzip Trac-0.12b1.zip
使用 .htaccess
尽管将上述配置重写为文档根目录中带有 .htaccess
文件的目录似乎微不足道,但这不起作用。Apache 会在任何 Trac URL 后附加一个“/”,这会干扰其正常运行。
可能可以使用 mod_rewrite 解决此问题,但我未能使其正常工作。总而言之,这得不偿失。
这也可以开箱即用,配置如下简单
SetHandler mod_python PythonInterpreter main_interpreter PythonHandler trac.web.modpython_frontend PythonOption TracEnv /system/path/to/this/directory PythonOption TracUriRoot /path/on/apache AuthType Basic AuthName "ProjectName" AuthUserFile /path/to/.htpasswd Require valid-user
TracUriRoot
显然是您需要在浏览器中输入以访问 Trac 的路径,例如 domain.tld/projects/trac
。
更多 .htaccess 帮助
如果您使用 .htaccess 方法,并且您的 Trac 目录继承了来自其他目录的 .htaccess 指令,您可能会遇到其他问题。这可能也有助于添加到您的 .htaccess 文件中
<IfModule mod_rewrite.c> RewriteEngine Off </IfModule>
平台特定问题
Win32 问题
如果您在 Windows 上使用 mod_python < 3.2 运行 Trac,上传附件将无法正常工作。此问题在 mod_python 3.1.4 或更高版本中已解决,请升级 mod_python 以修复此问题。
OS X 问题
在 OS X 上使用 mod_python 时,您将无法使用 apachectl restart
重启 Apache。此问题显然在 mod_python 3.2 中已修复,请升级 mod_python 以修复此问题。
SELinux 问题
如果 Trac 报告类似:Cannot get shared lock on db.lock
的信息,则可能需要设置仓库上的安全上下文
chcon -R -h -t httpd_sys_content_t PATH_TO_REPOSITORY
另请参阅 如何正确设置仓库权限?
FreeBSD 问题
FreeBSD ports 包含新旧版本的 mod_python 和 SQLite,但 pysqlite 和 mod_python 的早期版本无法集成
- pysqlite 需要 Python 中的线程支持
- mod_python 需要无线程安装。
Apache2 在 FreeBSD 上不自动支持线程。您可以在为 Apache 运行 ./configure
时强制启用线程支持,使用 --enable-threads
,但这不推荐。最佳选择似乎是在 /usr/local/apache2/bin/ennvars 中添加以下行
export LD_PRELOAD=/usr/lib/libc_r.so
Fedora 7 问题
请确保安装 'python-sqlite2' 包,因为它似乎是 TracModPython 所必需的,但 tracd 不需要。
Subversion 问题
如果您在 mod_python 环境下遇到 Trac 错误 Unsupported version control system "svn"
,即使它在命令行下甚至 TracStandalone 下都能正常工作,很可能是您忘记使用 PythonPath 指令添加 Python 绑定的路径。更好的方法是在 Python site-packages
目录中添加一个指向绑定的链接,或者在该目录中创建一个 .pth
文件。
如果不是这种情况,则可能是您使用的 Subversion 库与 Apache 的库二进制不兼容,通常是 apr
库的不兼容性导致的。在这种情况下,您也无法使用 Apache 的 svn 模块(mod_dav_svn
)。
您还需要一个最新版本的 mod_python
,以避免由于默认使用多个子解释器而导致的运行时错误(argument number 2: a 'apr_pool_t *' is expected
)。版本 3.2.8 应该可以工作,但为了强制使用主解释器,最好使用 #3371 中描述的解决方法
PythonInterpreter main_interpreter
这也是在使用 mod_python 中的 Subversion Python 绑定时出现的其他问题的推荐解决方法(#2611,#3455)。特别请参阅 Graham Dumpleton 在 #3455 中解释此问题的评论。
页面布局问题
如果 Trac 页面的格式看起来很奇怪,很可能是因为 Web 服务器未能正确处理控制页面布局的样式表。尝试将以下行添加到您的 Apache 配置中
Alias /myproject/css "/usr/share/trac/htdocs/css" <Location /myproject/css> SetHandler None </Location>
注意:为了使上述配置生效,它必须放在您的项目根位置配置之后,例如 <Location /myproject />
。
HTTPS 问题
如果您想在完全 HTTPS 下运行 Trac,您可能会发现它尝试重定向到普通的 HTTP。在这种情况下,只需在您的 Apache 配置中添加以下行
<VirtualHost *> DocumentRoot /var/www/myproject ServerName trac.mycompany.com SetEnv HTTPS 1 .... </VirtualHost>
php5-mhash 或其他 php5 模块导致的段错误
如果安装了 php5-mhash 模块,您可能会遇到段错误(在 Debian etch 上有报告)。尝试将其删除以查看是否能解决问题。请参阅 Debian 错误报告。
一些人在使用 PHP5 编译时自带的第三方库而不是系统库时也会遇到问题。请查看 Django 段错误。
另请参阅:TracGuide, TracInstall, ModWSGI, FastCGI, TracNginxRecipe