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
In this case both ways use Apache's URL rewriting module : mod_rewrite. You have to make sure you have it loaded or compiled in Apache.
Apache 1.x
In 1.x versions of the Apache web server, you must uncomment the following line in the main Apache configuration file, generally found at /etc/apache/apache.conf or /etc/httpd/httpd.conf :
LoadModule rewrite_module modules/mod_rewrite.so
Apache 2.x
Newer versions of Apache (> 2.x) uses a cleaner configuration system. In the directory /etc/apache2/mods-available/ are all modules loading and configuration snippets available. In /etc/apache2/mods-enabled/ are all enabled modules. You just need to check that a symlink to the rewrite module loading file is present. If not, create it :
cd /etc/apache2/mods-enabled/ ln -s ../mods-available/rewrite.load .
Don't forget to check that the LoadModule line in this file (rewrite.load) is uncommented :
LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
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"
The wimp way for multiple projects
For those of using simply the cgi solution, the trac.cgi can be copied/symlinked to other directories
<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>
The same works also for the authentication:
<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>
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.
Start out by creating a projects directory in your DocumentRoot (/var/www in this example). Projects will be accessed as http://hostname/projects/projectname. Copy (or symlink) trac.cgi to this projects/ directory together with a file named index.html. This will be shown when users try to access nonexistent projects.
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:
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>
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.
tracd and Trac Mod Python can also serve multiple projects.
Suggestion: In the second Rewrite Rule? directive and in the Location Match? directive, change [[:alnum:]] to [^/.] because while [[:alnum:]] only matches an alpha-numeric character, [^/.] matches any character that is not a slash or a dot. This change allows for, among other things, hyphens in project/directory names. It doesn't allow dots, because we don't want to match ".." for security reasons. Another possibility is to replace [[:alnum:]] with [[:alnum:]\-], which matches only an alphanumeric character or a hyphen (the backslash "escapes" the hyphen, which would otherwise have special meaning). The Apache 2.0 mod_rewrite documentation suggests referencing the Perl regular expression manual page (run perldoc perlre on a system where Perl is installed) for details on regular expressions. Note that it may be preferable to use a pattern that matches only characters suitable for directory names (and, thus, project names) that are valid for your particular installation.
Per-project authentication
As you problably noticed, the global procedure described above uses the same AuthUserFile, so every user you create in this file can log in every Trac project you host. Of course, in a non-configured Trac env, this user will be considered as anonymous, but you might not want this too. Using a per-project authentification also allows you to use a different authentification greater for each project.
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.
Preparation
As for the first procedure, you'll need a projects directory into your DocumentRoot. Copy or symlink trac.cgi to this project :
mkdir projects ln -s /usr/share/trac/cgi-bin/trac.cgi projects/trac.cgi
We will also use an index.cgi file (a Perl script) to list available projects. We will discuss its creation later. We will also take for granted that your Trac environments live in /var/lib/trac/.
Apache configuration
The begining is exactly the same than for the global authentification installation :
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>
But here comes the magic. For each directory found in /var/lib/trac/, we create the appropriate <Location> section in the Apache configuration, using an automated Perl loop(mod_perl is required). Paste in the following right after the <Directory> section in your Apache config file:
<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>
Auth files and project listing
In order to complete this setup, you will need two authentification files :
- /var/lib/trac/access.user, an htpasswd file listing all user logins and passwords. You can of course use one file per project (use $trac_path/$name.htpasswd as Auth User File? for example).
- /var/lib/trac/access.group, a group file, listing all authorized user per project, following this syntax :
proj1: user1 user2 proj2: user1 user3 proj3: user4
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:
#!/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__
Here you are ! Don't forget to chown these files to www-data, and it should work !
See also: Trac Guide, Trac Install, Trac Multiple Projects Windows?