= Trac and mod_python = Trac 0.7.1 and later supports [http://www.modpython.org/ mod_python], which speeds up Trac's response times considerably and permits use of many Apache features not possible with tracd/mod_proxy. Be sure to grab mod_python 3.1.3 and later for ''SetHandler'' ''mod_python'' directive to work. Also, older versions may generate an internal error. [http://projects.edgewall.com/trac/ticket/1090 #1090] == Trac Trunk Configuration == The examples below are written for Trac 0.8.x. If you are running Trac from the trunk source you will need to make a modification to the configuration. The mod_python handler class is changed in trunk revision [1287] and later, so you'll need to substitute the following line: {{{ PythonHandler trac.ModPythonHandler }}} with this one: {{{ PythonHandler trac.web.modpython_frontend }}} == Simple configuration == Here's a typical Trac CGI/Apache setup: {{{ ScriptAlias /projects/myproject /path/to/python/share/trac/cgi-bin/trac.cgi SetEnv TRAC_ENV /var/trac/myproject }}} The equivalent mod_python setup is: {{{ SetHandler mod_python PythonHandler trac.ModPythonHandler PythonOption TracUriRoot "/projects/myproject" PythonOption TracEnv /var/trac/myproject }}} Note that the option ''TracUriRoot'' may or may not be necessary in your setup. Try without first, and if the URLs produced by Trac look wrong or if Trac does not seem to recognize the URLs correctly, add the ''TracUriRoot'' option. Authentication works the same as for CGI: {{{ AuthType Basic AuthName "myproject" AuthUserFile /var/trac/myproject/.htaccess Require valid-user }}} == Setting up a project on the root of the webserver == To install Trac on the root of the webserver (in a virtual host context for example) and make it available at the ''!http://some-hostname/'' URL, use the following: {{{ ServerName trac.example.org Alias /trac /var/www/trac.example.org/htdocs/trac SetHandler mod_python PythonHandler trac.ModPythonHandler PythonOption TracUriRoot "/" PythonOption TracEnv /var/trac/myproject AuthType Basic AuthName "My Project" AuthUserFile /var/trac/myproject/.htaccess Require valid-user SetHandler None }}} The path in the last {{{}}} block should match your {{{htdocs_location}}}. The directive "{{{SetHandler None}}}" allows us to escape mod_python and have Apache serve the static files (located at {{{/var/www/trac.example.org/htdocs/trac/}}} on the filesystem in this example). Any other URLs will be handled by mod_python. == Setting up multiple projects == The Trac mod_python handler handler supports a configuration option similar to Subversion's {{{SvnParentPath}}}, called {{{TracEnvParentDir}}}: {{{ SetHandler mod_python PythonHandler trac.ModPythonHandler PythonOption TracUriRoot /projects PythonOption TracEnvParentDir "/var/trac" }}} When you request the {{{/projects}}} URL, you will get a (currently very simple) listing of all subdirectories of the directory you set as {{{TracEnvParentDir}}}. Selecting any project in the list will bring you to the corresponding Trac instance. You should make sure that the configured directory only contains Trac environment directories that match the currently installed Trac version, because that is not checked prior the the generation of the project list. === Use different locations for htdocs and mod_python === The mod_python location must be different than the trac htdocs location. For example, if you map Trac's htdocs location to {{{/trac}}} and then map your mod_python handler to {{{/trac}}} as well, you will encounter strange problems. == Setting up multiple projects as the root URL == Let's say you want something like http://projects.yourdomain.com which has a list of all of the projects hosted on it. However, you don't want to do manual configuration every time a new project is added. Or, you'd like to minimize it. Here's a quick sample: {{{ Alias /trac/ /usr/share/trac/htdocs/ Options Indexes MultiViews AllowOverride None Order allow,deny Allow from all SetHandler mod_python PythonHandler trac.ModPythonHandler PythonOption TracUriRoot / PythonOption TracEnvParentDir "/var/trac" AuthType Basic AuthName "Project1" AuthUserFile /var/www/projects.yourdomain.com/security/users AuthGroupFile /var/www/projects.yourdomain.com/security/groups Require group project1-users AuthType Basic AuthName "Project2" AuthUserFile /var/www/projects.yourdomain.com/security/users AuthGroupFile /var/www/projects.yourdomain.com/security/groups Require group project2-users SetHandler none }}} A few things to note about this example: all of the users are stored in one file, {{{/var/www/projects.yourdomain.com/security/users}}}. Groups for these users are defined in the groups file, {{{/var/www/projects.yourdomain.com/security/groups}}}. The Trac projects are all stored under {{{/var/trac}}}. To add a new project, you'll have to create a new user in the user file. Then, create a new group for the project in the group file. Finally, create a new block with a new {{{Require group}}} directive. That's about it. Note: It's untested, but you might be able to use the following setup to authenticate any number of projects: {{{ ... }}} == Troubleshooting == === Form submission problems === If you're experiencing problems submitting some of the forms in Trac (a common problem is that you get redirected to the start page after submission), check whether your {{{DocumentRoot}}} contains a folder or file with the same path that you mapped the mod_python handler to. For some reason, mod_python gets confused when it is mapped to a location that also matches a static resource. === Using .htaccess === Although it may seem trivial to rewrite the above configuration as a directory in your document root with a {{{.htaccess}}} file, this does not work. Apache will append a "/" to any Trac URLs, which interferes with its correct operation. It may be possible to work around this with mod_rewrite, but I failed to get this working. In all, it is more hassle than it is worth. Stick to the provided instructions. :) === mod_python does caching: beware === When using mod_python you have to reload apache before changes to a trac.ini of a project or a projects templates take effect! === Win32 Issues === If you run trac with mod_python on Windows, attachments will not work. There is a (simple) workaround for this which is to apply the patch attached to ticket [http://projects.edgewall.com/trac/ticket/554 #554]. === OS X issues === There is a mod_python issue on OSX: Look at the end of its README. You need to either define the environment variable DYLD_FORCE_FLAT_NAMESPACE before starting httpd or apply [http://www.dscpl.com.au/projects/vampire/PATCHES this patch] to mod_python. Also note that there is an error in the module when you build it from source. Basically an unpatched version will not respond correctly to the 'apachectl restart' command. If you issue this command on an unpatched module your client will receive a 500 error from apache. The patch needed to fix this problem is included below: {{{ --- src/mod_python.c Mon Feb 16 20:47:27 2004 +++ /Usersjkp/mod_python.c Wed Mar 16 21:15:49 2005 @@ -31,6 +31,10 @@ * (In a Python dictionary) */ static PyObject * interpreters = NULL; +#ifdef WITH_THREAD +static apr_thread_mutex_t* interpreters_lock = 0; +#endif + apr_pool_t *child_init_pool = NULL; /** @@ -124,6 +128,8 @@ name = MAIN_INTERPRETER; #ifdef WITH_THREAD + apr_thread_mutex_lock(interpreters_lock); + PyEval_AcquireLock(); #endif @@ -149,6 +155,8 @@ #ifdef WITH_THREAD PyEval_ReleaseLock(); + + apr_thread_mutex_unlock(interpreters_lock); #endif if (! idata) { @@ -469,6 +477,9 @@ const char *userdata_key = "python_init"; apr_status_t rc; + /* fudge for Mac OS X with Apache where Py_IsInitialized() broke */ + static int initialized = 0; + apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!data) { apr_pool_userdata_set((const void *)1, userdata_key, @@ -490,13 +501,16 @@ } /* initialize global Python interpreter if necessary */ - if (! Py_IsInitialized()) + if (initialized == 0 || ! Py_IsInitialized()) { + initialized = 1; /* initialze the interpreter */ Py_Initialize(); #ifdef WITH_THREAD + apr_thread_mutex_create(&interpreters_lock,APR_THREAD_MUTEX_UNNESTED,p); + /* create and acquire the interpreter lock */ PyEval_InitThreads(); #endif }}} ''Mar. 25/05'' The patch listed above causes complaints when attempting to apply it; also, the URL for the OS X patch is broken. I found that patch as well as an additional one for mod_python for use with a multithreaded MPM [http://www.dscpl.com.au/projects/vampire/patches.html here] (same site; pages have been shuffled around). ---- See also TracGuide, TracInstall, TracMultipleProjects