= Trac on Red Hat Enterprise Linux 5 = == Installing Trac software and dependencies == Installing Trac on Red Hat Enterprise Linux 5 is relatively easy thanks to [http://rpmforge.net RPMforge] packages from Dag and Dries. Visit http://dag.wieers.com/rpm/FAQ.php#B for details on how to configure your server to be able to access RPMforge. Once you have your server configured to use the RPMforge package repository, installing Trac is accomplished by running: {{{ yum install trac }}} Once the software is installed, you will need to configure it as documented below to get it up and going. == Configuration overview == This guide will result in the following configuration: * HTTP requests will be handled by Apache HTTP Server ("Apache"): * Trac will be run within its own separate and limited user account: * No Trac code will be executed inside Apache processes; * Trac data will be stored within a SQLite database; * All data files are owned/readable/writable only by the dedicated Trac user account; * HTTP requests will be proxied from Apache to Trac via mod_proxy_ajp. The rationale for this configuration is: * We can take advantage of Apache's features such as SSL, and advanced authentication (eg LDAP); * No extra code or modules that could effect the security or stability of the Apache server are introduced; * Individual instances of Trac are isolated and can have their resource usage easily measured; * Multiple versions of Trac could be run if so desired. If you are dedicating an entire machine to Trac and don't require such high levels of isolation, you may wish to simply embed Trac in Apache. See ["TracOnRHEL"] for details. It is a much simpler procedure. You may also want to simply just run the trac standalone daemon on a high port. It is assumed that Subversion is already installed/configured and in a working state. In the examples below, the end goal will to have a trac environment setup for PROJECT_NAME available at: https:''//trac.example.org/PROJECT_PATH === Creating the dedicated Trac account === Create a user account for Trac: {{{ $ su - # useradd -d /home/trac -c 'Trac server user' trac }}} Be sure to add the trac user to any groups necessary for access to your subversion repository. You may also need to add it to the group that owns the Apache password file so that it can authenticate users. === Create a new project environment === {{{ # su - trac $ mkdir -p -m 0700 $HOME/projects $ trac-admin $HOME/projects/PROJECT_NAME initenv }}} See TracInstall for generic information. === Web server gateway === In order to connect Apache to Trac we will make use of http://trac.saddi.com/flup which is an AJP to WSGI gateway. Download the latest prepackaged tarball version of flup into the trac account and install: {{{ $ tar zxf flup-0.5.tar.gz $ cd flup-0.5 $ mkdir -p -m 0700 $HOME/lib/python $ PYTHONPATH=$HOME/lib/python python setup.py install --home=$HOME }}} Now we need to create a simple gateway: {{{ $ mkdir -m 0700 $HOME/bin }}} then create the file '''$HOME/bin/ajp_to_wsgi_gateway''' with the following contents: {{{ #!python #! /usr/bin/python # # # AJP to WSGI gateway to run Trac. import os, sys # System path configuration. Nasty hack below. sys.path.append(os.environ['HOME'] + '/lib/python/setuptools-0.6c3-py2.4.egg') sys.path.append(os.environ['HOME'] + '/lib/python/flup-0.5-py2.4.egg') def usage() : print """Usage: ajp_to_wsgi_gateway PATH_TO_TRAC_ENV URL_PREFIX PORT""" sys.exit(1) if __name__ == '__main__': if len(sys.argv) != 4 : usage() else : path = sys.argv[1] prefix = sys.argv[2] port = int(sys.argv[3]) # WSGI application configuration. os.environ['TRAC_ENV'] = path os.environ['PYTHON_EGG_CACHE'] = path + '/eggs' import trac.web.main application = trac.web.main.dispatch_request # AJP to WSGI gateway. import logging from flup.server.ajp import WSGIServer ret = WSGIServer(application, bindAddress=('localhost', port), scriptName=prefix, loggingLevel=logging.ERROR, debug=False ).run() sys.exit(ret and 42 or 0) }}} You may need to modify the script above to fixup the system path information. Set the permissions on the script: {{{ chmod 700 $HOME/bin/ajp_to_wsgi_gateway }}} Create '''$HOME/bin/trac_server_wrapper''' with the following contents: {{{ #! /bin/bash # # Wrapper script to start a trac server for multiple environments. export PYTHONPATH=$HOME/lib/python trac_project() { local trac_env=$1 local path_prefix=$2 local port=$3 local status=42 while test $status -eq 42; do $HOME/bin/ajp_to_wsgi_gateway "$trac_env" "$path_prefix" $port status=$? done & } # Individul project servers. trac_project $HOME/projects/PROJECT_NAME /PROJECT_PATH SERVER_PORT }}} Edit the script to replace PROJECT_NAME, PROJECT_PATH, and SERVER_PORT as appropriate. PROJECT_PATH must not have a '/' after it and does not include the protocol or hostname. Set the permissions on the script: {{{ chmod 700 $HOME/bin/trac_server_wrapper }}} Set the server script to start on system boot: {{{ $ cat < cron.fragment @reboot $HOME/bin/trac_server_wrapper EOF $ crontab cron.fragment $ rm cron.fragment }}} Now start the gateway: {{{ trac_server_wrapper }}} === Alternative web server interface === At the time of writing, the above scripts appear to have problems with escape sequences in URLs. For example, this will mean you can't put spaces in milestone names, and you won't be able to browse source files whose names contain spaces. There is however an alternative way of presenting an AJP interface to Apache which can be configured to avoid this problem, and yet retain the advantages of running Trac in its own user account. The way to do this is to run `tracd` with `--protocol=ajp` and the `--unquote` switch that was added in trac 0.11.4 (if you're running an earlier version, refer to [/attachment/ticket/8128/t8128-tracd-unquote-r7943.patch this patch]). For example: {{{ tracd --auth="*",/var/www/passwords/passwd,MyRealm --port=SERVER_PORT --hostname=localhost --protocol=ajp --unquote --env-parent-dir=$HOME/projects --base-path=/PROJECT_PATH --daemonize --pidfile=$HOME/trac.pid --umask=63 }}} but all one line. It's probably easiest to put this in a shell script somewhere. You'll need to add this to the `trac` user's crontab to be executed at each reboot. === Common web content === Now we copy the common icons, stylesheets, etc that Apache will server directly into our hosting account: {{{ $ mkdir -m 0701 $HOME/public_html $ cp -a /usr/share/trac/htdocs/* $HOME/public_html/trac $ chmod 701 $HOME }}} Edit '''$HOME/projects/PROJECT_NAME/conf/trac.ini''' and adust the following values: * In the ''[header_logo]'' section set ''src'' to ''/trac/trac_banner.png'' * In the ''[project]'' section set ''icon'' to ''/trac/trac.ico'' * In the ''[trac]'' section set ''htdocs_location'' to ''https''://trac.example.org/trac'' === Start trac servers === Start trac by running: {{{ $ trac_server_wrapper }}} === SELinux configuration === Apache will need network access in order to communicate to the trac daemon. As root run: {{{ # setsebool httpd_can_network_connect on }}} For Apache to be able to access the common trac files, the will need to be correctly labeled. As root run: {{{ # fixfiles restore /home/trac }}} === Apache configuration === Create your SSL certificate for trac.example.org. As root: {{{ # cd /etc/pki/tls/certs # make trac.example.org.crt }}} Make sure the ''mod_ssl' package is installed. Create an Apache virtual host in ''/etc/httpd/conf/httpd.conf'' (or an included file) with contents like: {{{ ServerName trac.example.org:443 ServerAdmin support@example.org DocumentRoot /home/trac/public_html CustomLog logs/trac.example.org_log combined ErrorLog logs/trac_error_log SSLEngine on SSLCertificateFile /etc/pki/tls/certs/trac.example.org.crt SSLCertificateKeyFile /etc/pki/tls/private/trac.example.org_key #SSLCACertificateFile /etc/pki/tls/certs/A_CA_CERT.crt # Security restrictions. # Require password authentication via LDAP. #AuthType basic #AuthName "Trac" #AuthBasicProvider ldap #AuthLDAPURL ldap://localhost/dc=example,dc=org #AuthLDAPGroupAttribute memberUID #AuthLDAPGroupAttributeIsDN off #require ldap-group cn=devel,ou=Groups,dc=example,dc=org #Order Allow,Deny #Allow from staff.example.org # Trac runs as a daemon inside the 'trac' account. # It is written in Python, however there is a # AJP <-> WSGI gateway that handles the requests on # a per project basis. Redirect /PROJECT_PATH https://trac.example.org/PROJECT_PATH/ ProxyPass /PROJECT_PATH/ ajp://localhost:SERVER_PORT/PROJECT_PATH/ ProxyPassReverse /PROJECT_PATH/ ajp://localhost:SERVER_PORT/PROJECT_PATH/ }}} Check the syntax via '''service httpd configtest''' and restart via '''service httpd restart'''. Everything should now work! === Troubleshooting === The above is quite complicated and easy to make a mistake with. Things to check: * Check the apache server error log and the trac user error log; * Check with ''ps xfwww'' that ''ajp_to_wsgi_gateway'' is running; * Check with ''netstat -tunlp'' that the gateway is listening on the correct port; * Modify ''ajp_to_wsgi_gateway'' and set ''debug'' to ''True'' and ''loggingLevel'' to ''logging.DEBUG'' to see the requests hit the gateway; * Modify ''$HOME/projects/PROJECT_NAME/conf/trac.ini'' and set ''log_type'' to ''stderr'' to get error messages from trac itself.