pvillega’s posterous

pvillega’s posterous

Pere Villega  //  Born in Barcelona, living in Dublin, and tagged as geek since youth. Developer in the path to becoming a software architect. I swear this is not a proper blog :)

Feb 16 / 7:50am

Install Trac using Nginx and Git

Introduction

This guide explains how to install Trac in your server to manage your personal projects, using Nginx as webserver and Git as code repository.

Trac is an open source, web-based project management and bug-tracking tool. The program is inspired by CVSTrac, and was originally named svntrac due to its ability to interface with Subversion. It is developed and maintained by Edgewall Software. Trac is written in the Python programming language. Until mid-2005, it was available under the GNU General Public License; since version 0.9, it has been released under a modified BSD license. Both are free software licenses.

Trac allows hyperlinking information between a computer bug database, revision control and wiki content. It also serves as a web interface to a version control system like Subversion, Git, Mercurial, Bazaar and Darcs. Prior to version 0.11 the web front end presentation of Trac was handled by the ClearSilver template system. Starting with 0.11 an in-house template system called Genshi is used, although compatibility with ClearSilver based plugins will remain for several versions.

Nginx (pronounced "engine X") is a lightweight web server/reverse proxy and e-mail (IMAP/POP3) proxy, licensed under a BSD-like license.Originally, nginx was developed to fill the needs of various websites run by Rambler. According to the December 2008 Netcraft survey, nginx is now used on 3,354,329 domains, making it the fourth most popular web server, being used at sites like Wordpress, Penny-Arcade or YouPorn.

Git is a free distributed revision control, or software source code management project with an emphasis on being fast. Git was initially created by Linus Torvalds for Linux kernel development. Every Git working directory is a full-fledged repository with complete history and full revision tracking capabilities, not dependent on network access or a central server. Several high-profile software projects now use Git for revision control, most notably the Linux kernel, Perl 5, Samba, X.org Server, Qt (toolkit), One Laptop per Child (OLPC) core development, Ruby on Rails web framework, VLC, Merb, Wine, SWI Prolog, DragonFly BSD and the Android mobile platform.

Requirements

This document assumes you are using an Ubuntu 8.04 server. This guide can be probably used with newer versions of Ubuntu and Debian, but some minor changes may be required. We will install Trac 0.11. It requires:
  • Python 2.5
  • PostgreSQL as database (Trac 0.11 has some bugs when using MySQL).
  • Nginx as HTTP-proxy (Apache could be used but this configuration is simpler to setup and runs faster)
It is recommended you apply all available patches (security and upgrade) to your server before proceeding.

Postgres

If you don't have Postgres installed in your server you can follow these instructions before proceeding with the installation. To install Postgres and all required packages run:
$ sudo apt-get install postgresql postgresql-client postgresql-contrib python-psycopg2
This will deploy the database, create the link so it runs as daemon and configure the "postgres" user (root user of the database). It will also add the Python libraries so we can access the database from Trac. Once installed, we need to change the default "postgres" password. To do that execute:
$ sudo su postgres -c psql template1
This will log you into the PostgreSQL console. There run:
template1=# ALTER USER postgres WITH PASSWORD 'new_password';
Now we need to set the password for the Ubuntu postgresql user. Execute:
$ sudo passwd -d postgres
$ sudo su postgres -c passwd
Now restart the server.
$ sudo /etc/init.d/postgresql-8.3 restart
The server should be running, try to log again using:
$ sudo su postgres -c psql template1
Be aware this has created a database server which only has localhost access, so it won't be available from other servers. If you want to allow connection from an external ip, you have to edit pg_hba.conf.

Installation steps

Those steps assume you have an user with "sudo" privileges. You only need a console, no UI required.

Installing Trac

First of all we need some packages before we install Trac. Run:
$ sudo apt-get install build-essential graphviz apache2-utils htmldoc enscript
Once those components are installed, you can install Trac using "easy_install", the Python installer. Run:
$ sudo easy_install Trac
$ sudo easy_install http://svn.edgewall.org/repos/genshi/trunk/ #A required component, install after Trac to avoid problems
Now you can configure the database and create the Trac user. Log into PostgreSQL:
$ su postgres -c psql
and run:
template1=# create user
with password 'user_password';

template1=# create database
with owner=user
encoding = 'utf8';

Now you have a user for Trac connectivity and a database to be used by one of your projects. Next step is to create the Trac environment. To this end, choose a folder (available to Nginx) as root folder for all your Trac projects. Inside this folder we will create several subfolders, one per project. This has to be done this way as Trac only allows one project per "environment", so if you want to manage several projects you need to run several Trac instances in parallel in the same server. Luckily this is not a huge overhead as the embedded Trac server is quite efficient.

To create the first project I will assume you've choose "/public/" as you root folder and this folder is accessible by Nginx. To initialize your environment run:
$ trac-admin /public/projectname initenv
This will ask some questions about the project. When you are asked for the PostgreSQL connection string, write:
postgres://trac_db_user:password@localhost:5432/database
You are done, your Trac server is configured and ready to go. To test it, use the embedded Trac server:
$ tracd -p 3050 /public/projectname
Be aware this (probably) can't be accessed from outside your box as the port will be closed. Just check it works with Lynx or a similar browser.

Use nginx as proxy

As said before, the server is not yet available from outside the box (if it is, you have a security issue here!). Setting Nginx as proxy is quite easy. Go to your "nginx/sites-available" folder and edit the file of the domain you will use to access the Trac server. You can use this configuration as an example:
upstream domain_trac {
server 127.0.0.1:3050;
}


server {

listen 80;
server_name domain.com;
rewrite ^/(.*) http://www.domain.com/$1 permanent;
}

server {
listen 80;
server_name www.domain.com;

access_log /home/public_html/domain.com/log/access.log;
error_log /home/public_html/domain.com/log/error.log;


location / {
proxy_pass http://domain;
proxy_redirect default;
}
}

Restart Nginx and you are done. Nginx will be a simple proxy of your "tracd" server, redirecting all the requests received. This is a more flexible and fast configuration than the one using mod_cgi on Apache or a similar server. Also it allows you to kill an instance of Trac easily and without affecting other running Trac instances under the same proxy.

Enabling user authentication

Probably you want some privacy for your project, or simply avoiding anybody can edit the wiki. To this end you can enable user authentication. This section does a brief description, you will find more detail at your own Trac server, under http://www.domain.com/ProjectName/wiki/TracStandalone. User authentication is based on basic HTTP authentication, using Apache password files. Go to your root ("/public/") folder and run:
$ sudo htpasswd -c /public/ProjectName/.htpasswd username
This will request the password of the user and save it in the .htpasswd file. You can select another path outside the project folder if you want, but it has to be accessible by nginx and tracd. Now you have to notify Trac that you own a password file and want to use it for authentication. To this end, you have to launch the Trac server with some parameters:
$ tracd -p 3050 --basic-auth=ProjectName,/public/ProjectName/.htpasswd,domain.com /public/ProjectName/

Add Admin user

Once you enable authentication, there is no default admin user. You need to add at least one user to the admin group to be able to configure Trac properly. Run:
$ trac-admin /public/ProjectName/ permission add  TRAC_ADMIN
Be careful, <user> has to be an existing user with a valid password in the .htpasswd file. For more details, check your own Trac instance at http://www.domain.com/ProjectName/wiki/TracPermissions

Running multiple projects at once

As said before, Trac only allows one project per environment (folder). If you want to manage more projects, you have to create new folders under the root directory (in this tutorial, "/public/") and initialize each one independently. Then you can tell tracd to run them all at once. If you want to share the access permissions between all the projects, run:
$ tracd -p 8080 --auth="*",/public/ProjectName/.htpasswd,domain.com  /public/project1 /public/project2
For other configurations check your own Trac instance at http://www.domain.com/ProjectName/wiki/TracStandalone

Integrate with Git

As it is now, our Track instance only provides a Wiki and a ticketing system. To use the full power of Trac we need to link some code repository to it. Our choice is Git for several reasons (performance, usage, etc). This assumes you have installed a Gitosis repository in your server that can be used to store the git code. The integration is done using the Git plugin for Trac, available at http://trac-hacks.org/wiki/GitPlugin. This page also contains steps to install the plugin. You just need to download the zip file, unzip it and run:
$ cd gitplugin/0.11/
$ sudo easy_install .
Once the plugin is installed, our next step is to clone the Gitosis administration file and edit it:
$ git clone git@YOUR_SERVER_HOSTNAME:gitosis-admin.git
$ cd gitosis-admin
$ nano gitosis.conf
Add the new group and repository related to the project:
[group coreteam]
writable = projectname
members = username@desktop
and commit the changes to the Gitosis server:
$ git commit -a -m "allowing access to projectname to user username"
$ git push
Now create your initial repository:
$ mkdir projectname
$ cd projectname
$ git init
$ git remote add origin git@YOUR_SERVER_HOSTNAME:projectname.git
# do some work
$ git add new files
$ git commit -a -m "first commit"
$ git push origin master:refs/heads/master
You have created your repository and submitted the first files. Now log into your Gitosis server and edit the file "gitosis/repositories/projectname/description". Change the content as required and set its owner to "git:webmasters" (chown). This step is important to avoid issues when pushing new code to the repository. Now you just need to edit "/public/projectname/conf/trac.ini" and add the references to git:
[components]
tracext.git.* = enabled

[git]
cached_repository = true
git_bin = /usr/bin/git
persistent_cache = true
shortrev_len = 7

[trac]
repository_dir = /home/git/repositories/game.git
repository_type = git

Configuration

Now that we have a running Trac instance, we have to configure it. You should check your Trac documentation at http://www.domain.com/ProjectName/wiki/TracIni to see what kind of customizations you can do using the "trac.ini" file (for example, sending emails to users).

Change reporting system

The default ticket reports are not very user-friendly. To fix that and use a better system, edit "trac.ini":
[components]
trac.ticket.report.* = disabled

Add Spam filter

If you allow anonymous users to edit your content, you will probably need a spam filter. The one we will use needs an Akismet key to filter spam. To install it run:
$ sudo easy_install TracSpamFilter
Once installed, edit "trac.ini" and add:
[akismet]
api_key = 1234567890

Enable XML-RPC

XML-RPC allows 3rd party applications to connect to Trac. This is required if you will use Netbeans or Eclipse to interact with Trac. The offical plugin is located at http://trac-hacks.org/wiki/XmlRpcPlugin, but it has some issues with custom workflows, which causes problems with the Cube'N plugin of Netbeans. As we use Netbeans, we need to use the fixed pluguin from http://code.google.com/p/cubeon/downloads/list, TracXMLRPC-1.5.0-py2.5.egg. Download the file and install it using:
$ sudo easy_install racXMLRPC-1.5.0-py2.5.egg
Then edit trac.ini and add:
[components]
tracrpc.* = enabled
Restart Trac.

Running Trac as daemon

There are some scripts to launch Trac (using tracd) as a Linux daemon, but the few I've tested have issues when running under Ubuntu. The easiest solution is to launch tracd using “nohup”. This should suffice for most user. When I find a working init.d script I will copy it here.

Static content

For performance reasons, static content (like non-code files) should be put in the $TRAC_ENV/htdocs folder, and is accessed by URLs like <project_URL>/chrome/site/.... There's a wiki label for them: "htdocs:file_name".
Loading mentions Retweet

Filed under // git nginx scm trac

Comments (3)

Feb 16 / 7:47am

Gitosis - Git repository

This article was originally located here. It explains how to install a Git repository on your sever using Gitsosis. It allows you to store several projects using just user accounts and a SSH key to authenticate those users (thus adding a security layer on top). I've copied the contents of the article as I find it quite useful and I personally think Git is probably one of the best SCM nowadays.

Credit goes to the author, I'm just storing it. If you ever read this, thanks a million man!

The rest of this article will be a tutorial showing you how to host and manage Git repositories with access control, easily and safely. I use an up and coming tool called gitosis that my friend Tv wrote to help make hosting git repos easier and safer. It manages multiple repositories under one user account, using SSH keys to identify users. However, users do *not* need shell accounts on the server, instead they will talk to one shared account that does not allow arbitrary commands. Git itself is used to setup gitosis and manage the Git repos, which pleases the recursion-seeking orthogonal CS-side of my brain.

Assumptions: I take my examples from a Ubuntu Linux server. While I haven't tested other systems, I imagine different Linux distributions, FreeBSD, OS X, etc... would be similar. Gitosis is written in Python, so you should have a copy of Python installed as well. Enough talk, let's get down and dirty.

Install gitosis

gitosis is a tool for hosting git repositories (I'm repeating myself for those who skim :) The first thing to do is grab a copy of gitosis and install it on your server:

cd ~/src
git clone git://eagain.net/gitosis.git

Notice that gitosis is extremely light-weight. The clone takes a mere couple seconds. Less is more, and I like that a lot. Next, install it like so:

cd gitosis
python setup.py install

Don't use --prefix unless you like self-inflicted pain. It is possible to install gitosis in a non-standard location, but it's not nice. Read the Caveats section at the bottom and then come back here. If you get this error:

-bash: python: command not found

or

Traceback (most recent call last):
File "setup.py", line 2, in ?
from setuptools import setup, find_packages
ImportError: No module named setuptools

You have to install Python setuptools. On Debian/Ubuntu systems, it's just:

sudo apt-get install python-setuptools

For other systems, someone tell me or leave a comment, so I can update this section and improve this tutorial. The next thing to do is to create a user that will own the repositories you want to manage. This user is usually called git, but any name will work, and you can have more than one per system if you really want to. The user does not need a password, but does need a valid shell (otherwise, SSH will refuse to work).

sudo adduser \
--system \
--shell /bin/sh \
--gecos 'git version control' \
--group \
--disabled-password \
--home /home/git \
git

You may change the home path to suit your taste. A successful user creation will look similar to:

Adding system user `git'...
Adding new group `git' (211).
Adding new user `git' (211) with group `git'.
Creating home directory `/home/git'.

You will need a public SSH key to continue. If you don't have one, you may generate one on your local computer:

ssh-keygen -t rsa

The public key will be in $HOME/.ssh/id_rsa.pub. Copy this file to your server (the one running gitosis). Next we will run a command that will sprinkle some magic into the home directory of the git user and put your public SSH key into the list of authorized keys.

sudo -H -u git gitosis-init < /tmp/id_rsa.pub

id_rsa.pub above is your public SSH key that you copied to the server. I recommend you put it in /tmp so the git user won't have permission problems when trying to read it. Success looks like:

Initialized empty Git repository in ./
Initialized empty Git repository in ./

(Yes, two times) For good measure, let's make sure the post-update hook is set executable. I've seen it where sometimes it doesn't get set (problem with older setuptools):

sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update

Here some cool magic happens. Run this on your local machine:

git clone git@YOUR_SERVER_HOSTNAME:gitosis-admin.git
cd gitosis-admin

You will now have a gitosis.conf file and keydir/ directory:

~/dev/gitosis-admin (master) $ ls -l
total 8

-rw-r--r-- 1 garry garry 104 Nov 13 05:43 gitosis.conf
drwxr-xr-x 3 garry garry 102 Nov 13 05:43 keydir/

This repository that you just cloned contains all the files (right now, only 2) needed to create repositories for your projects, add new users, and defined access rights. Edit the settings as you wish, commit, and push. Once pushed, gitosis will immediately make your changes take effect on the server. So we're using Git to host the configuration file and keys that in turn define how our Git hosting behaves. That's just plain cool.

From this point on, you don't need to be on your server. All configuration takes place locally and you push the changes to your server when you're ready for them to take effect.

Creating new repositories

This is where the fun starts. Let's create a new repository to hold our project codenamed FreeMonkey. Open up gitosis.conf and notice the default configuration:

[gitosis]           

[group gitosis-admin]
writable = gitosis-admin
members = jdoe

Your "members" line will hold your key filename (without the .pub extension) that is in keydir/. In my example, it is "jdoe", but for you it'll probably be a combination of your username and hostname. To create a new repo, we just authorize writing to it and push. To do so, add this to gitosis.conf:

[group myteam]
members = jdoe
writable = free_monkey

This defines a new group called "myteam", which is an arbitrary string. "jdoe" is a member of myteam and will have write access to the "free_monkey" repo. Save this addition to gitosis.conf, commit and push it:

git commit -a -m "Allow jdoe write access to free_monkey"
git push

Now the user "jdoe" has access to write to the repo named "free_monkey", but we still haven't created a repo yet. What we will do is create a new repo locally, and then push it:

mkdir free_monkey
cd free_monkey
git init
git remote add origin git@YOUR_SERVER_HOSTNAME:free_monkey.git

# do some work, git add and commit files
git push origin master:refs/heads/master

NOTE: nkadel states "You missed a booby trap: before doing the 'mkdir free_monkey', you need to get clear of the gitosis-admin repository. Overall this works well to setup the repository, and to provide project space. But to import projects from other repositores, one should also do this inside the free_monkey directory: git pull --tags [remote repository]" Be aware of that!

With the final push, you're off to the races. The repository "free_monkey" has been created on the server (in /home/git/repositories) and you're ready to start using it like any ol' git repo.

Adding users

The next natural thing to do is to grant some lucky few commit access to the FreeMonkey project. This is a simple two step process. First, gather their public SSH keys, which I'll call "alice.pub" and "bob.pub", and drop them into keydir/ of your local gitosis-admin repository. Second, edit gitosis.conf and add them to the "members" list.

cd gitosis-admin
cp ~/alice.pub keydir/
cp ~/bob.pub keydir/
git add keydir/alice.pub keydir/bob.pub

Note that the key filename must have a ".pub" extension. gitosis.conf changes:

 [group myteam]
- members = jdoe
+ members = jdoe alice bob
writable = free_monkey

Commit and push:

git commit -a -m "Granted Alice and Bob commit rights to FreeMonkey"
git push

That's it. Alice and Bob can now clone the free_monkey repository like so:

git clone git@YOUR_SERVER_HOSTNAME:free_monkey.git

Alice and Bob will also have commit rights.

Public access

If you are running a public project, you will have your users with commit rights, and then you'll have everyone else. How do we give everyone else read-only access without fiddling w/ SSH keys? We just use git-daemon. This is independent of gitosis and it comes with git itself.

sudo -u git git-daemon --base-path=/home/git/repositories/ --export-all

This will make all the repositories you manage with gitosis read-only for the public. Someone can then clone FreeMonkey like so:

git clone git://YOUR_SERVER_HOSTNAME/free_monkey.git

To export only some repositories and not others, you need to touch git-daemon-export-ok inside the root directory (e.g. /home/git/repositories/free_monkey.git) of each repo that you want public. Then remove "--export-all" from the git-daemon command above.

More tricks

gitosis.conf can be set to do some other neat tricks. Open example.conf in the gitosis source directory (where you originally cloned gitosis way at the top) to see a summary of all options. You can specify some repos to be read-only (opposite of writable), but yet not public. A group members list can include another group. And a few other tricks that I'll leave it to the reader to discover.

Caveats

If /home/git/.gitosis.conf on your server never seems to get updated to match your local copy (they should match), even though you are making changes and pushing, it could be that your post-update hook isn't executable. Older versions of setuptools can cause this. Be sure to fix that:

sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update

If your Python goodies are in a non-standard location, you must additionally edit post-update and put an "export PYTHONPATH=..." line at the top. Failure to do so will give you a Python stack trace the first time you try to push changes within gitosis-admin. If you want to install gitosis in a non-standard location, I don't recommend it. It's an edge case that the author hasn't run up against until I bugged him to help me get it working. For the brave, you need to edit whatever file on your system controls the default PATH for a non-login, non-interactive shell. On Ubuntu this is /etc/environment. Add the path to gitosis-serve to the PATH line. Also insert a line for PYTHONPATH and set it to your non-standard Python site-packages directory. As an example, this is my /etc/environment:

PATH="/home/garry/sys/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games"
PYTHONPATH=/home/garry/sys/lib/python2.4/site-packages

Be sure to logout and log back in after you make these changes. Don't use the gitosis-init line I have above for the standard install, instead use this slightly modified one:

sudo -H -u git env PATH=$PATH gitosis-init < /tmp/id_rsa.pub

Be sure to also set PYTHONPATH in your post-update hook as described above. The *should* do it. I am purposefully terse with this non-standard setup as I think not many people will use it. HIt me up in #git on FreeNode if you need more info (my nick is up_the_irons).

Non-standard SSH port

If you run SSH on a non-standard port on your server, don't use the syntax "git@myserver.com:1234:/foo/bar", it won't work. Putting the port in the URL doesn't seem to make gitosis, or git, (not sure which) happy. Instead, put this in your ~/.ssh/config file:

Host myserver.com
Port 1234

Conclusion

Well, I hope you enjoyed this tutorial and that it makes your Git hosting life easier. This is public revision 10. Please let me know if you find mistakes, omissions, an easier way than what I described, etc...

 

Loading mentions Retweet

Filed under // git gitosis scm

Comments (0)