Serving Mercurial using Apache on Ubuntu
If you have even the slightest interest in revision control systems chances are you have been keeping an eye on the development of distributed systems. The dust has not settled yet but I think that Sun’s decision to go with Mercurial for OpenSolaris and OpenJDK makes that particular program a fairly safe choice. Some history on Sun’s choice here. A good and fairly recent comparison here. Don’t miss out on Linus Torvald’s recommendations to the KDE people.
I have only very briefly tried out distributed revision control systems. The point that stands out for me is the powerful idea of the dual push-pull model. First there is the pull model; sandboxed development where one or more developers collaborate, pulling sources from each other. Each user is responsible for pulling changes from others and the model requires close collaboration and communication. This is the development model usually described and advertised for distributed revision control systems.
The second development model is the push model where changes are pushed to one or more central, master repositories, much like you would check in sources into Subversion or any other centralized version control system. For commercial projects, you will probably want to support this second mode, setting up master repositories that represents the stable state of your project. Sooner or later you will need HTTP read access to the masters. If nothing else, how else will your Hudson build server access the stable branch?
I really like Mercurial’s serve command that starts serving your repository over HTTP. Just type hg serve and others can access your repository for pulling over the net, just like that. This is not what you want for your master repositories though. For those you will want a permanent solution and that means using CGI scripts.
The Mercurial book contains a chapter about serving HTTP using CGI that is a good starting point. There are also a few posts on the net that I also found useful, here and here. The instructions below have been tested on a blank Ubuntu 7.10 (Jeos) box. I have chosen Apache as the web server.
I choose to place the root of the Mercurial repositories at /srv/hg/. See the FHS for more information on that choice. Serving HTTP access is made using a CGI script, shipped with Merurial. I prefer to place the script next to the repositories in a directory called /srv/hg/cgi-bin/.
# mkdir /srv/hg
# mkdir /srv/hg/cgi-bin
Below, I’ve chosen to copy the hgwebdir.cgi script which enables access to multiple repositories using the same root.
# cp /usr/share/doc/mercurial/examples/hgwebdir.cgi /srv/hg/cgi-bin/
# chmod a+x /srv/hg/cgi-bin/hgwebdir.cgi
Create a file /srv/hg/cgi-bin/hgweb.config that contains the following two lines:
[collections]
/srv/hg/ = /srv/hg/
And that’s it as far as Mercurial goes. Just remember that it is Apache that will run the mercurial commands through the CGI scripts. It means that you will need to give read access to the world for the repositories
# chmod a+rX /srv/hg/your repo(s)
All that’s left to do is setting up a web server to serve the Mercurial CGI script above. There are several servers to choose from. I’ve chosen to use Apache:
# apt-get install apache2
Rather than edit the default site, I find it cleaner to setup a separate, new Merurial site. Create a new file /etc/apache2/sites-available/hg and add the following lines:
NameVirtualHost *
<VirtualHost *>
ServerAdmin webmaster@localhost
DocumentRoot /srv/hg/cgi-bin/
<Directory "/srv/hg/cgi-bin/">
SetHandler cgi-script
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/hg.log
</VirtualHost>
Disable the default site, enable our new Mercurial site and reload the Apache server.
# a2dissite default
# a2ensite hg
# /etc/init.d/apache2 reload
That’s it. You should now be able to see all your repositories if you point your browser to http://yourhost/hgwebdir.cgi/
January 17th, 2009 at 2:58
Hmm.. doesn’t quite work for me … are you sure thats the right web browser address to go to?
January 17th, 2009 at 3:58
Never mind. Got it working
Had the directory path wrong and some of the permissions on the directories as well …
January 17th, 2009 at 14:28
Glad you got it working, cg. If I remember correctly, I ran the entire setup as described above on a fresh install but if you found any errors above, please let me know and I’ll correct them.
May 25th, 2009 at 14:53
I get the following error:
: ‘hgweb’ object is not callable
args = (“‘hgweb’ object is not callable”,)
message = “‘hgweb’ object is not callable”
(BTW – this is the same error I got following the Mercurial’s Definitive Guide).
I am guessing Python is running, as the ‘colourful’ error page shows on the heading:
Python 2.5.2: /usr/bin/python
Mon May 25 13:53:19 2009
Any ideas / suggestions?
May 25th, 2009 at 14:54
There was HTML escaping… in the error message, I got:
<type ‘exceptions.TypeError’>
May 25th, 2009 at 18:47
So did you get it working, Marco? If not, are you running a Debian system?
June 4th, 2009 at 14:42
Thanks a lot man
August 25th, 2009 at 14:50
The easiest setup i found so far!!
Thanks man
October 12th, 2009 at 16:40
Thanks a lot!!! Just one thing /srv/hg = /srv/hg you should finish each with / like /srv/hg/ = /srv/hg/ because mine didn’t work until I made it.
Thanks
October 13th, 2009 at 21:12
Thanks Sergey, I just made the change you suggested.
February 12th, 2010 at 6:53
Thank you, the instructions are very clear! However, i have what I am sure is a minor problem.
I’m on the latest Ubuntu. I followed everything carefully but when i navigate to http://localhost i get a 403 Forbidden error.
there’s only two chmods so i can’t imaginve where i went wrong.
February 12th, 2010 at 22:27
Steve, I’ll bring up a fresh Ubuntu and have a look as soon as possible.
March 24th, 2010 at 14:41
Steve, what about using http://localhost/hgwebdir.cgi as per the instructions?
March 24th, 2010 at 15:20
Well, time has obviously not been permitting but I’ll give it a shot tonight. Follow me on twitter if you want updates. http://twitter.com/maltenstedt
March 24th, 2010 at 20:28
Steve, I just brought up a fresh Ubuntu 9.10 (Jeos) and followed the instructions above to the letter and it works for me. Perhaps you have a more complex Apache setup than the one I describe?
April 10th, 2010 at 23:23
Thank you for this nice guide. Made life alot easier for a linux noob like myself.