Edgewall Software

Version 15 (modified by anonymous, 15 years ago) ( diff )

How to use Nginx as your main web server for multiple Trac Projects

This recipe below is actually a very simple set up but the instructions did not make it obvious so let me explain. This set up is perfect if you use Nginx as your main webserver. First you set up Nginx as your main web server. Then you set up multiple instances of Tracd Web Server. (Trac has an embedded webserver that is included with Trac by default and this webserver is called Tracd.) Then you have Nginx serve requests to your Tracd web server instances.

Why you should use Tracd behind Nginx

This is an easy set up which allows Nginx to act as an excellent load balancer. Tracd is lightweight and fast and its easy to get working with your Trac projects. You can start multile instances of the Tracd web server on different ports for different Trac projects. Nginx as your main webserver can serve requests to these various running instances of the Tracd web server. This also works for multiple Trac Projects on multiple vhosts. In short its fast, lightweight, and easy to set up.

Here are the steps you need to take.

  1. Set up Nginx as your main webserver (on port 80)
  2. Start multiple instances of the Tracd embedded web server on different ports for each Trac Project
  3. Configure Nginx to serve requests to your various running instances of Tracd Webserver.

Using Tracd with Nginx in Cluster Mode

I am intensely dissatisfied with Trac and Apache. We have multiple vhosts, and multiple trac sites per vhost. When we tried upgrading from Subversion 1.2.3 we hit this bug.

  • apache/mod_python still occasionally segfaults.
  • apache/mod_python was causing strange occasional delays. (Likely related to the segfaults).
  • We would like to upgrade to SVN 1.4

Caveat: Only use this with PostgreSQL. If you want to do this, but are on SQLite, then use Pacopablos Sqlite-to-Pg. We use it here, and it's great.

Tracd - Trac's light and fast embedded web server

Run multiple tracd instances. This offers a speed benefit if you use FasterFox, as well as good multi-user concurrency responsiveness.

Using the Gentoo init system, it was easy to create simple init scripts (which I attatched to this page). Here is a simplified example, which makes for easier wiki'ing

Multi-Site tracd Startup
Works with trac-0.10 and up.

tracd -d -p 3050 --pidfile=/var/live/run/tracd.3050 --protocol=http -e /var/live/trac

Single-Site tracd Startup
note: will not work with anything pre 0.10.

tracd -d -p 3050 --pidfile=/var/live/run/tracd.5051 --protocol=http -s /var/live/trac/telecardia

Nginx

Get Nginx, the Excellent Apache Replacement by Igor Sysoev. Install it. I use Gentoo, and all of my examples are based on Gentoo. Gentoo packagers create /etc/nginx.

/etc/nginx/nginx.conf

http {
  include         /etc/nginx/mime.types;
  default_type    application/octet-stream;

  include         /etc/nginx/nginx-defaults.conf;

  upstream live_trachosts_com {
          server  127.0.0.1:3050;
          server  127.0.0.1:3051;
          #[... up to the number of instance, or more, if you want to be free to add more ...]
  }
  
  server {
          listen          192.168.1.254:80;
          server_name     live.trachosts.com live;
  
          access_log      /var/log/nginx/live.access.log main;
          error_log       /var/log/nginx/live.error_log info;
  
          location / {
                  proxy_pass      http://live_trachosts_com;
                  include         /etc/nginx/proxy.conf;
          }
  
  }

Nginx + SSL

You might be asking about ssl - here is what we do for ssl: /etc/nginx/nginx.conf

http {
  include         /etc/nginx/mime.types;
  default_type    application/octet-stream;

  include         /etc/nginx/nginx-defaults.conf;

  upstream live_trachosts_com {
          server  127.0.0.1:3050;
          server  127.0.0.1:3051;
          #[... up to the number of instance, or more, if you want to be free to add more ...]
  }
  
  server {
          listen          192.168.1.254:80;
          server_name     live.trachosts.com live;
  
          access_log      /var/log/nginx/live.access.log main;
          error_log       /var/log/nginx/live.error_log info;
  
          location / {
                  rewrite         ^/(.*)$ https://imrlive.com/$1 redirect;
          }
  
  }
  server {
          listen          192.168.1.254:443;
          server_name     live.trachosts.com live;
  
          access_log      /var/log/nginx/live.access.log main;
          error_log       /var/log/nginx/live.error_log info;
  
          ssl                  on;
          ssl_certificate      /etc/nginx/ssl/_nginx.cert;
          ssl_certificate_key  /etc/nginx/ssl/traclive.key;
          keepalive_timeout    70;
          add_header           Front-End-Https    on;

          location / {
                  proxy_pass      http://live_trachosts_com;
                  include         /etc/nginx/proxy.conf;
          }
  
  }
}

Static Content
Serving static files from htdocs dir ala /<site>/chrome/site aliases http://live.trachosts.com/myproj/chrome/site to /var/trachosts/trac/myproj/htdocs

        location ~ /(.*?)/chrome/site/ {
                rewrite /(.*?)/chrome/site/(.*) /$1/htdocs/$2 break;
                root    /var/trachosts/trac;
        }

Subversion

This section isn't necessary if you're using tracd so long as you start tracd as follows.

/usr/bin/python /usr/bin/tracd -d -p 3050 --basic-auth projec1,/var/www/trac/project1/db/users.htdigest,svn --pidfile=/var/www/trac/tracd.3050 --protocol=http -e /var/www/trac

We still need to get access to subversion via Apache mod_dav_svn. I created a vhost in apache for _only_ the svn URLs. Other people will not use this setup, which is good for them.

Listen 127.0.0.1:80
<VirtualHost *:80>
    ServerAdmin webmaster@trachosts.com

    # in order to support COPY and MOVE, etc -  over https (443),
    # ServerName _must_ be the same as the nginx servername
    ServerName live.trachosts.com 
    UseCanonicalName on

    DocumentRoot "/var/www/live.trachosts.com/htdocs"

    <Directory "/var/www/live.trachosts.com/htdocs">
        Options FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>

  # Subversion Configuration
  <IfModule mod_dav_svn.c>
      <Location /svn>
          DAV svn 
          SVNParentPath /var/live/svn
          AuthType Basic
          AuthName "Client Trac Sites - Subversion Repository"
          AuthUserFile /var/live/conf/users
           <IfModule !mod_authz_svn.c>
              AuthzSVNAccessFile /var/live/conf/svnauthz
          </IfModule>
          Require valid-user
      </Location>
  </IfModule>
</VirtualHost>

Add this to the server section of the Nginx config. (in the :80 line, or the :443, whatever)

location /svn {
        proxy_pass      http://127.0.0.1:80;
        include         /etc/nginx/proxy.conf;
        set  $dest  $http_destination;
        if ($http_destination ~ "^https://(.+)") {
           set  $dest   http://$1;
        }
        proxy_set_header  Destination   $dest;
}

Script Examples

start-meta-site.sh

INSTANCES="3050 3051 3052 3053 3054 3055 3056"
USER="apache"
VERSION="0.10.1"
#ENV="/var/live/trac"
PIDFILE="/var/live/run/tracd"
### Extra Args here, for instance --basic-auth
#ARGS="--basic-auth=${ENV},${ENV}/vccbob.pwd,FarQ"
ARGS="-e /var/live/trac"
PYTHON_EGG_CACHE="/var/live/egg_cache"

function start(){
    export PYTHON_EGG_CACHE
    for I in $INSTANCES; do
        su ${USER} -c "/usr/bin/tracd -d -p ${I} --pidfile=${PIDFILE}.${I} --protocol=http ${ARGS} ${ENV}"
        done
}

function stop(){
   for x in `ls ${PIDFILE}.*}`; do
       kill `cat ${x}`
       done
}

$1

start-single-site.sh

INSTANCES="3050 3051 3052"
USER="apache"
VERSION="0.10.1"
ENV="/var/lib/trac-single"
PIDFILE="/var/lib/trac-single/run"
### Extra Args here, for instance --basic-auth
#ARGS="--basic-auth=${ENV},${ENV}/vccbob.pwd,FarQ"
ARGS="--basic-auth=${ENV},${ENV}/vccbob.pwd,FarQ ${ENV}"
PYTHON_EGG_CACHE="${ENV}/egg_cache"

function start(){
    export PYTHON_EGG_CACHE
    for I in $INSTANCES; do
        su ${USER} -c "/usr/bin/tracd -d -p ${I} --pidfile=${PIDFILE}.${I} --protocol=http ${ARGS} ${ENV}"
        done
}

function stop(){
   for x in `ls ${PIDFILE}.*`; do
       kill `cat ${x}`
       done
}

$1

Todo

  • Nginx Authentication Howto
  • Post the actualy config files somewhere.

Questions

  • is this possible with client certificate authentication?

See also TracFastCgi#SimpleNginxConfiguration

Note: See TracWiki for help on using the wiki.