Hosting Websites on Bare Minimum VPS/Dedicated Servers

Running Trac + Git Hosting on a Low End VPS

Tags: , , Date/Time: August 31, 2010 @ 2:59 am, by LowEndAdmin

Trac Any user of Version Control System? When I started as a programmer back in the 90’s it was RCS. Then moved to CVS when I joined my first start up. About 5 years ago I moved everything — work projects and personal projects — to Subversion. And these days I use Git for my personal projects. While I could pay someone (GitHub for example, or RepositoryHosting which is quite cheap for unlimited repositories), for a peace of mind I would rather host the shared central repositories myself and organise my own backups.

At the same time I would like to have a bug/enhancement tracking system to track and to prioritize my work. A wiki for documentation would be a bonus (if I ever have time to write docos). Trac fits the bill. I know there is also RedMine but I am a Python developer it’s just easier for me to write plugins for Trac.

This will (hopefully) be a step-by-step guide to install both Git and Trac 0.12 on a Ubuntu 10.04 system. I used my 6 pound/year RackVM VPS in UK to write this HOWTO. 256MB burstable memory is more than enough.

Do note that this is not a tutorial on how to use git or any other distributed version control system. See Git’s website if you wish to learn more about it.

1. Setting up a Low End Box

To get the basics running,

  1. Get an empty VPS, but feel free to use one that is already deployed for something else — in this case feel free to skip this method and just make sure Nginx is installed.
  2. Refer to the lowendscript article to set up a low end VPS with Exim4 and Nginx running.
# wget http://github.com/lowendbox/lowendscript/raw/master/setup-debian.sh
# bash setup-debian.sh system
# bash setup-debian.sh exim4
# bash setup-debian.sh nginx

2. Install Git and Set up Master Repository

Make sure git is installed. We are also creating a git user under /home/git as the home of all repositories.

# apt-get install -y git-core
# useradd -m -K UMASK=027 git

Now you have a “git” user. You could set it up with git-shell as restricted login shell (which also needs to be added to /etc/shells), however I found it’s too restrictive, especially when I also want to be able to copy the repositories around with scp. You will also need to decide how to authenticate it — with password or with pubkeys so you can log in to push/pull the git repositories in there.

For example I want to create copy my lowendscript repository there. I will do this on my home computer (assuming running Linux).

$ cd ~/proj/lowendscript
$ git clone --bare . /tmp/lowendscript.git
$ scp -r /tmp/lowendscript.git git@my-gitbox:
$ git remote add origin git@my-gitbox:lowendscript.git

Replace “my-gitbox” with the hostname of your VPS. scp would only work after you have set up authentication for user “git” (password or pubkey).

You should now be able to push/pull from the central shared repository.

3. Install Trac

Ubuntu 10.04 LTS only comes with Trac 0.11 but I really wanted to use Trac 0.12 because of better multi-repositories support. So instead of apt-get install trac, we are going the long way and downloading and installing it manually. The Trac installation guide is a good reference, as well as Git plugin for Trac.

Let’s get some Python dependencies installed first, and then use easy_install to install Trac and Git plugin. Note that Genshi 0.6 is required for Trac so we won’t be using the 0.5 from Ubuntu repo.

# apt-get install python python-setuptools python-pygments python-tz subversion
# easy_install Trac
# easy_install http://trac-hacks.org/svn/gitplugin/0.12

I will now create a trac user to run the standalone instance, and initialize our first Trac project. Note that I am adding user trac into git group so it can have read access to the git repositories.

# useradd -m -K UMASK=077 -G git trac
# sudo -u trac trac-admin ~trac/project initenv

Just put in your new project’s name (that can be changed later), and use the default for the rest. Done! You have a Trac project created, and it’s time to get the Trac standalone server up and running.

# sudo -u trac tracd -s -p 8000 --pidfile ~trac/project/tracd.pid -d ~trac/project

You should be able to connect to port 8000 on your VPS via your browser to see it up and running. However, a plain vanilla Trac installation is not very useful. We need to get authentication working first so you can administer your Trac install from its web interface. You can find more info on setting up authentication for Trac standalone server here. Need to get apache2-utils installed first so we can use htpasswd.

I’ll also create a “lowendadmin” user with password “12345”.

# apt-get install apache2-utils
# sudo -u trac htpasswd -bc ~trac/project/htpasswd lowendadmin 12345
Adding password for user lowendadmin

We will also need to grant WebAdmin permission to the user “lowendadmin”. Now restart Trac to use the htpasswd file we have just created.

# [ -e ~trac/project/tracd.pid ] && kill `cat ~trac/project/tracd.pid`
# sudo -u trac trac-admin ~trac/project permission add lowendadmin TRAC_ADMIN
# sudo -u trac tracd -s -p 8000 --pidfile ~trac/project/tracd.pid -d --basic-auth="*,/home/trac/project/htpasswd,Project" ~trac/project

When you log back into Trac (port 8000 on your VPS), you should be able to see a “Login” link. Click on that to bring out the HTTP Basic Authentication dialog box that prompts for username/password. Once authenticated, you’ll be back at Trac with “Admin” link at the top navigation bar.

4. Adding Git Repository to Trac

Once you have Admin enabled on Trac, it can be all GUI work from now. First you need to enable GitPlugin for Trac.

  1. Click on “Admin” at top right.
  2. Click on “Plugins” on the left navigation menu, under “General”
  3. Click on “TracGit” in the middle of the page, enable “GitConnector” and Save Change

Next, you need to add your repositories using the Admin interface.

  1. Click on “Repositories” on the left navigation menu, under “Version Control”
  2. In my lowendscript example, I put
    • Name=lowendscript
    • Type=git
    • Directory=/home/git/lowendscript.git
  3. Click on Add! And you should now be able to browse your source under “Browse”

That’s pretty much it for Trac. It would be a good idea to put that long tracd command in /etc/rc.local so it starts everytime you reboot the VPS.

5. SSL + Proxy via Nginx

Now, you do want your latest source code browser + bug tracking system behind SSL, right? I found the easiest way to do it is by putting a Nginx proxy in front. Since we already have Nginx installed in step 1, we just need to

  • Get a SSL certificate.
  • Add Nginx configuration to do the proxy.

For “free” SSL certificates, I use StartSSL, which works for most modern browsers. However to make it simple, I am going to use self-signed certificate in this tutorial.

# openssl genrsa -out /etc/nginx/ssl.key 1024
Generating RSA private key, 1024 bit long modulus
e is 65537 (0x10001)
# openssl req -new -key /etc/nginx/ssl.key -out /tmp/ssl.csr
Country Name (2 letter code) [US]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:my-gitbox
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# openssl x509 -req -days 365 -in /tmp/ssl.csr -signkey /etc/nginx/ssl.key -out /etc/nginx/ssl.crt
Signature ok
subject=/C=US/ST=Some-State/O=Internet Widgits Pty Ltd/CN=my-gitbox
Getting Private key
# rm -f /tmp/ssl.csr

Done. Your self signed SSL key and certificate are now installed. Time to get Nginx to use it. Save the following file to /etc/nginx/sites-enabled/my-gitbox.conf:

server {
    server_name _;
    listen 443;
    ssl on;
    ssl_certificate /etc/nginx/ssl.crt;
    ssl_certificate_key /etc/nginx/ssl.key;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    location /trac/chrome/site {
        rewrite /trac/chrome/site/(.*) /htdocs/$1 break;
        root    /home/trac/project;

Restart Nginx, and now browse to your VPS’s HTTPS port. You’ll see Trac in its SSL glory (well, after bypass the browser’s security check at least).

Trac also happens to have pretty good Wiki engine, and it has heaps of plugins for customization. With a bit of optimization (most notably reducing the stack size for multi-threaded tracd), you should be able to run the entire stack with less than 80MB on an OpenVZ VPS (and much less on a Xen).

Now with code repository, bug tracking system and documentation wiki ready, I better get back to do more coding :)


  1. Wow! very helpful post, I was also thinking this morning to setup Trac on my RackVM (but its a XEN). I use Subversion mostly, how do you compare Subversion with Git? Wanted to hear it from a developer who actually uses it. I on the other hand, only use subversion, never used Git.

    August 31, 2010 @ 4:32 am | Reply
  2. Subversion is a strictly centralized repository, and I think it has already passed its hey days. Comparing to git,

    – It is a lot slower
    – Not distributed so every diff, every branch, every commit etc has to go to server
    – .svn/ inside every directory sucks.
    – Subversion over HTTP works only Apache + WebDAV = very bloated
    – Did I mention *slow*?!

    On the other hand you can check out just a sub-tree of Subversion repository, or use svn:externals to connect two different repos. Very useful to put code from all over the place together. No equivalent in Git.

    August 31, 2010 @ 5:03 am | Reply
    • Tom:

      I agree with all points, but the .svn in every directory is history now, and this alone improved speed considerably. But I absolutely agree, git is way superior.

      September 2, 2013 @ 1:38 pm | Reply
  3. Wouldn’t mind seeing some memory utilisation stats for this, that way we can all work on ‘trimming’ where possible ;).

    August 31, 2010 @ 5:16 am | Reply
  4. FZ:

    Nice post. Does this setup allow you to pull/push to the git repository via http with the same credentials that you have with trac?

    August 31, 2010 @ 5:19 am | Reply
  5. @FZ — no. Git *can* support HTTP based repository for pulling but not for pushing. SSH-based is probably the best. The set up is probably only good for personal projects or a very small team.

    @Hughesey — After a few page views this is my process list:

    # ps uax
    root         1  0.0  0.5   2464  1360 ?        Ss   Aug02   0:00 init
    root      9673  0.0  0.2   1964   708 ?        S    Aug02   0:00 /usr/sbin/syslo
    root      9780  0.0  0.3   2300   816 ?        Ss   Aug02   0:00 cron
    root      3296  0.0  0.3   2420   924 ?        Ss    0:18   0:00 /usr/sbin/xinet
    102      28357  0.0  0.3   6620   888 ?        Ss    0:25   0:00 /usr/sbin/exim4
    root     12078  0.0  0.2   4744   700 ?        Ss    2:53   0:00 nginx: master p
    www-data 12079  0.0  1.0   5724  2712 ?        S     2:53   0:00 nginx: worker p
    root     18183  0.0  0.4   2736  1300 ?        Ss    5:20   0:00 dropbear -i
    root     23946  0.0  0.6   3020  1692 pts/0    Ss    5:20   0:00 -bash
    trac     32275  4.9  6.9  63888 18176 ?        S     5:22   0:03 /usr/bin/python
    root      1543  0.0  0.3   2356   860 pts/0    R+    5:23   0:00 ps --sort=start
    # free -m
                 total       used       free     shared    buffers     cached
    Mem:           256         67        188          0          0          0
    -/+ buffers/cache:         67        188
    Swap:            0          0          0

    Note that the tracd process (pid=32275) has much bigger VSZ than RSS, i.e. it allocates a lot more memory than actually uses them. It seems to be common amongst scripting environments (Python). Also it’s a multi-threaded application so each thread would allocate its own stack.

    August 31, 2010 @ 5:28 am | Reply
  6. Vlad:

    LEA is so damn sexy :-)

    August 31, 2010 @ 9:13 pm | Reply
  7. thekreek:

    I have been thinking in RedMine, unfortunately it runs on Ruby, so it asks for a lot of memory. Have any of you try Indefero, its based on php (http://www.indefero.net/open-source/). What are your opinions about it. (No advertising intended).

    September 3, 2010 @ 8:51 am | Reply
    • ibk:

      Indefero missing Milestone feature of Trac

      January 7, 2011 @ 9:14 am | Reply
  8. Hmm interesting project. I will give that a try. With PHP the configuration would be even easier. Thanks.

    September 3, 2010 @ 1:19 pm | Reply
  9. glad i found this, i seam to have missed it when you first posted it.

    just got my repository set up but i have to reference it by its full path when i connect to it any ideas whats causing it (i.e. /home/git/repo rather then just repo)

    September 6, 2010 @ 3:40 pm | Reply
  10. Trac usually needs to know the full path of the repository before it can connect to it and read the data out. And I think it applies to Subversion under Trac as well.

    September 6, 2010 @ 11:27 pm | Reply
  11. Nick:

    This is one very useful guide, thanks!

    September 22, 2010 @ 5:03 am | Reply
  12. rs:

    just gave this a try and ran into the following error:

    The following error occurred while trying to extract file(s) to the Python egg
      [Errno 13] Permission denied: '/root/.python-eggs'
    The Python egg cache directory is currently set to:
    Perhaps your account does not have write access to this directory?  You can
    change the cache directory by setting the PYTHON_EGG_CACHE environment
    variable to point to an accessible directory.

    presumably this is because I did this as root which is causing some permissions trouble? how do you suggest avoiding this?

    October 9, 2010 @ 7:36 am | Reply
    • Which command produces the above error?

      October 9, 2010 @ 9:17 am | Reply
      • rs:

        It was at the step:

        # sudo -u trac trac-admin ~trac/project initenv

        October 9, 2010 @ 11:51 am | Reply
        • How about using

          # sudo -H -u trac trac-admin ~trac/project initenv

          Or replace all the sudo with sudo -H (as I just realised that I have my `sudo` aliased to `sudo -H`).

          October 9, 2010 @ 11:53 am | Reply
        • Derek Barnett:

          @LEA The -H switch did the trick.

          October 27, 2010 @ 8:42 pm | Reply
  13. rs:

    I think that did it?

    Another couple things though:
    easy_install http://trac-hacks.org/svn/gitplugin/0.12
    didn’t work for me following these directions until after I did a
    easy_install -U setuptools

    In addition, I ran into another error:
    sudo -H -u trac htpasswd -bc ~trac/project/htpasswd adminuser adminpassword
    htpasswd: cannot create file /home/trac/project/htpasswd

    October 10, 2010 @ 1:22 pm | Reply
    • rs:

      Whooops that other error is a mistake because I made a typo earlier. The instructions are right, and I have fat fingers.

      October 11, 2010 @ 10:03 am | Reply
  14. tsj5j:

    LEA, before I follow your guide (I’m a SVN user), do you need one tracd process per repository or is it one tracd process covering multiple repos? I manage many small projects so being able to create and remove repositories quickly would be very useful.

    Plus, is there a way to add repositories purely from Trac alone, or is the creation via command line necessary?

    November 3, 2010 @ 4:46 pm | Reply
    • For trac 0.12+ one single tracd can cover multiple repositories. You can go into the admin area to add new repositories (provided the tracd instance can read the directory). You can even add multiple of svn, git or hg directories, provided appropriate plugins are installed.

      When you get into Trac,

      1) Click on Admin (top navigation bar)
      2) Click on Version Control/Repositories on the left navigation bar
      3) You can then add new repositories there by giving them name, type (git, svn) and directory

      November 3, 2010 @ 9:49 pm | Reply
  15. Silly question but what do you use for a windows client for git? I know about tortoisesvn for svn and I see that it has a plugin for git. Does that work ok?

    May 1, 2011 @ 12:00 am | Reply
    • fanovpn:

      I use msysgit, but I guess you mean a GUI (though gitk and “git gui” both work on msysgit). TortoiseGit certainly seems to be fairly recommended. I’m not sure if it’s a plugin for tortoisesvn, I get the impression it’s more of a standalone “port” to git.

      May 1, 2011 @ 2:17 am | Reply
  16. Oh and I get an error with the trac-hacks line:

    # easy_install http://trac-hacks.org/svn/gitplugin/0.12
    Downloading http://trac-hacks.org/svn/gitplugin/0.12
    error: Unexpected HTML page found at http://trac-hacks.org/svn/gitplugin/0.12
    May 1, 2011 @ 12:02 am | Reply
    • fanovpn:

      That command works fine for me, maybe your easy_install (which is part of python setuptools) is out of date? The page mentions bugfixes in 0.6c9 to detect svn urls better. You can update setuptools with ‘easy_install -U setuptools’, but that might not work / might cause problems with your distribution’s package manager (unless you’re using a virtualenv).

      You could also try installing pip, which is a popular (and really nice) alternative to the easy_install script that comes with setuptools. pip should be able to identify that url as an svn repo better, and you can use ‘pip install svn+http://trac-hacks.org/svn/gitplugin/0.12’ to be sure it does. Pip is probably available in a package for your distribution (mine calls the package python-pip) for a system-wide install.

      I think pip is also installed by default into python virtualenvs, if you’re using one. If you aren’t, you might want to consider it. They keep all your python packages separate and let you have a set of them installed ‘locally’ for just a specific package (like Trac), and then update them without affecting any of the other versions of the modules for other packages. They’ve kind of become the recommended way to work on or install anything python these days, though I haven’t ever checked if Trac works in one.

      May 1, 2011 @ 3:04 am | Reply
    • Yes these days I have switched to python-virtualenv + pip. Here’s my current setup:

      $ bin/pip freeze
      May 2, 2011 @ 10:12 am | Reply
    • Thanks. I gave up after a couple of hours of beating my head against the table and went with a free service for the time being.

      May 2, 2011 @ 12:19 pm | Reply
  17. paul:

    You should also know about Fossil, http://fossil-scm.org .

    Kind of like git/trac/wiki all rolled into one, written in C and uses sqlite, so more suited for LEB hosting. It has shortcomings compared to git, but some people really like it.

    October 5, 2011 @ 7:31 pm | Reply
    • Will it run on Nginx?

      October 5, 2011 @ 8:53 pm | Reply
    • Thanks. Will take a look. Trac was used for its wealth of plugins and ease of development (easier to hack in Python than in C), but you are right that a simple C based backend would probably use less memory.

      October 6, 2011 @ 2:17 am | Reply
      • paul:

        I installed it and have been playing with it and looking at the code. It was very easy to get running, it is responsive serving pages from my AlienVPS 192mb OpenVZ, and it has its own embedded httpd (or you can run it as a cgi under nginx or whatever). The process footprint when running a clone of the fossil-scm.org site (they let you do that with a “fossil clone” operation) is about 1MB, not bad at all. The code looks pretty hackable since most of the heavy lifting is done by sqllite and so the C code is mostly a wrapper around a bunch of SQL calls. There are some things I’d have done differently but overall it’s a very clever program.

        October 7, 2011 @ 7:28 pm | Reply
  18. mike:

    @LowEndAdmin you should add this to the howto.

    nginx as a ssl proxy is mostly working, but sometimes is trac going back to http. for example:


    if I click on “save changes” the page is sending request over http and it stays there. I have to manually correct it again.

    to solve that change following settings in /home/trac/projects/conf/trac.ini
    base_url = https://my-gitbox
    use_base_url_for_redirect = true

    October 14, 2011 @ 6:54 pm | Reply
  19. Pingback: Bug Tracking with Trac and Git

  20. I have learned lot of things from it on the topic of blogging. thanks.BDWEBIT.COM

    December 28, 2014 @ 7:17 pm | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Quoting webhostingtalk.com URL seems to get binned consistently here, but I do peek into the spam box frequently to publish those comments.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

Your email address will not be published. Required fields are marked *