Configure Apache for multiple projects

By following these instructions, you will set up Apache to automatically serve multiple Trac projects for you. There are two different ways of setting this up: with and without global authentication. And with Apache 2 there are even two ways to do both.

Easiest method for hosting multiple projects in one domain with Apache 2

The first way to support multiple projects is to add the following to the Apache 2 config file, per project (myproj in this case):

[[ScriptAlias]] /myproj /path/to/trac.cgi

<Location "/myproj">
    [[SetEnv]] TRAC_ENV "/var/trac/myproj" 
</Location>

<Location "/myproj/login">
    [[AuthType]] basic
    [[AuthName]] "myproj - trac" 
    [[AuthUserFile]] "/var/svn/svn-auth-file" 
    Require valid-user
</Location>

This is in addition to the global line:

Alias /trac "/usr/share/trac/htdocs" 

If you want different users per project, just edit the AuthUserFile line for each one.

Harder method: URL Rewriting


h3. Apache 1.x

<pre>

<pre>
[[LoadModule]] rewrite_module modules/mod_rewrite.so
</pre>

h3. Apache 2.x

<pre>

<pre>
cd /etc/apache2/mods-enabled/
ln -s ../mods-available/rewrite.load .
</pre>

<pre>

<pre>
[[LoadModule]] rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
</pre>

This is Debian and Gentoo(?) specific. On [[SuSE]] you edit /etc/sysconfig/apache2 and add rewrite to APACHE_MODULES. Depending on your [[SuSE]] version you have to run "SuSEconfig --module apache2" or just "rcapache2 restart" 

h2. The wimp way for multiple projects

For those of using simply the cgi solution, the trac.cgi can be copied/symlinked to other directories

<pre>
<Location "/cgi-bin/project1/trac.cgi">
        [[SetEnv]] TRAC_ENV "/home/trac/project1" 
</Location>

<Location "/cgi-bin/project2/trac.cgi">
        [[SetEnv]] TRAC_ENV "/home/trac/project2" 
</Location>
</pre>

The same works also for the authentication:
<pre>
<Location "/cgi-bin/project1/trac.cgi/login">
[[AuthType]] Basic
[[AuthName]] "Project1" 
[[AuthUserFile]] /home/web/.access-files/trac.project1.htpasswd
Require valid-user
</Location>

<Location "/cgi-bin/project2/trac.cgi/login">
[[AuthType]] Basic
[[AuthName]] "Project2" 
[[AuthUserFile]] /home/web/.access-files/trac.project2.htpasswd
Require valid-user
</Location>
</pre>

h2. Global authentication

This is the simplest case. With this procedure, you will be able to serve multiple Trac projects, using the same user accounts for every projects (permissions are still per project, but authentication is not). This is the original procedure provided by the Trac team.

<pre>

Then create your Trac projects with trac-admin. It's important that they are all placed in the same directory. In this example we'll use /var/lib/trac. Add to your Apache configuration:

<pre>
[[RewriteEngine]] on
[[RewriteRule]] ^/projects/+$            /projects/index.html [L]
[[RewriteCond]] /var/lib/trac/$1            -d
[[RewriteRule]] ^/projects/([[:alnum:]]+)(/?.*)    /projects/trac.cgi$2 [S=1,E=TRAC_ENV:/var/lib/trac/$1]
[[RewriteRule]] ^/projects/(.*)            /projects/index.html

Alias /trac/ /usr/share/trac/htdocs/
#or where you installed the trac htdocs

#You have to allow people to read the files in htdocs
<Directory "/usr/share/trac/htdocs">
        Options Indexes [[MultiViews]]
        [[AllowOverride]] None
        Order allow,deny
        Allow from all
</Directory>

<Directory "/var/www/projects">
    AllowOverride None
    Options [[ExecCGI]] -MultiViews +SymLinksIfOwnerMatch
    AddHandler cgi-script .cgi
    Order allow,deny
    Allow from all
</Directory>

<LocationMatch "/projects/[[:alnum:]]+/login">
    AuthType Basic
    AuthName "trac" 
    AuthUserFile /path/to/trac.htpasswd
    Require valid-user
</LocationMatch>
</pre>

Now, when you add another project, you don't need to edit any apache config. The only file you may want to edit is index.html to make it list the new project. If you think this is too much work, replace it with a python cgi script that does it for you.

[[TracStandalone|tracd]] and [[TracModPython]] can also serve multiple projects.

<pre>

h2. Per-project authentication

<pre>

The procedure we are going to explain here is a bit more complicated than the previous one as it imply Perl scripting, and that you'll need to reload the Apache configuration when you add a new project. But it's also much more _tweakable_.

h3. Preparation

<pre>

<pre>
mkdir projects
ln -s /usr/share/trac/cgi-bin/trac.cgi projects/trac.cgi
</pre>

<pre>

h3. Apache configuration

The begining is exactly the same than for the global authentification installation :

<pre>
[[RewriteEngine]] On

[[RewriteRule]] ^/projects/+$                       /projects/index.cgi [L]
[[RewriteCond]] /var/lib/trac/$1                    -d

[[RewriteRule]] ^/projects/([[:alnum:]]+)(/?.*)     /projects/trac.cgi$2 [S=1,E=TRAC_ENV:/var/lib/trac/$1]
[[RewriteRule]] ^/projects/(.*)                     /projects/index.cgi

Alias /trac "/usr/share/trac/htdocs" 
<Directory "/var/www/projects">
  [[AddHandler]] cgi-script .cgi
  Options Indexes [[MultiViews]] SymLinksIfOwnerMatch +ExecCGI
  [[AllowOverride]] None
  Order allow,deny
  Allow from all
</Directory>
</pre>

<pre>

<pre>
<code class="perl">
<Perl>
#!/usr/bin/perl

# trac environments location
my $trac_path = "/var/lib/trac";

# trac base url
my $trac_location = "/projects";

opendir(TRAC_ROOT, $trac_path) or die "Unable to open Trac root directory ($trac_path)";

while (my $name = readdir(TRAC_ROOT))
{
  if ($name =~ /^[[:alnum:]]+$/)
  {
    $Location{"$trac_location/$name/login"} = {
      [[AuthType]] => "Basic",
      [[AuthName]] => "\"Trac authentification for $name\"",
      [[AuthUserFile]] => "$trac_path/access.user",
      [[AuthGroupFile]] => "$trac_path/access.group",
      Require => "group $name",
    };
  }
}

closedir(TRAC_ROOT);

+END+
</Perl>
</code></pre>

h3. Auth files and project listing

In order to complete this setup, you will need two authentification files :

<pre>
<pre>
<pre>
proj1: user1 user2
proj2: user1 user3
proj3: user4
</code></pre>

For the project listing, we create another Perl script which will basically do the same as in the static Apache configuration above. Cut and paste the following into /projects/index.cgi:

<pre>
<code class="perl">
#!/usr/bin/perl

use strict;

my $trac_path = "/var/lib/trac";
my $trac_location = "/projects";

# Send header
print "Content-Type: text/html\n\n";

# Send content
print "<html>\n";
print " <head>\n";
print "  <title>Project listing</title>\n";
print " </head>\n\n";
print " <body>\n";
print "   <h1>Project listing</h1>\n";
print "   <ul id=\"trac\">\n";

opendir(ROOT, $trac_path)
        or die "Unable to open root directory ($trac_path)";

while (my $name = readdir(ROOT))
{
  if ($name =~ /^[[:alnum:]]+$/)
  {
    print "   <li><a href=\"$trac_location/$name\">" . ucfirst($name) . "</a></li>\n";
  }
}

closedir(ROOT);

print "   </ul>\n";
print " </body>\n";
print "</html>\n";

+END+
</code></pre>

<pre>

-------
See also: [[TracGuide]], [[TracInstall]], [[TracMultipleProjectsWindows]]