Nginx and Mercurial setup

Some weeks ago I switched to Nginx and quit Apache and was quite happy with it. I was so happy that completely forgot about my Mercurial repositories hosted on same server. This happen when I was in hurry and needed to push and pull some changes,  damn.

At first I quickly restored Apache, did all needed changes and switched back to Nginx. For sure, I did not like this way and explored how I can connect Mercurial directly to Nginx. I was quite surprised how easy it is and how flexible.

Mercurial via Apache setup


I had Mercurial setup through Apache in a very standard way.

/var/hg – Holding all my repositaries


/var/hg/hgwebdir.cgi – For Apache CGI support

/var/hg/hguser – for user passwords in htpasswd format

Apache configuration was the following

Switch to Nginx was really painless.

Nginx and Mercurial setup

Prepare Mercurial

First step I switched to FastCGI instead of CGI. To do this I copied file hgwebdir.fcgi to my repo root /var/hg and made it executable

Or grab the file here

Next step is to install something that can spawn FastCGI processes, sine Nginx can not do this by itself.  This is easy with spawn-cgi

I configured it via local unix socket instead of TCP port, it seems to me this way it is more secure. Run it like this:

At first start I’ve run into the problem

After running with “-n” switch to see debug output, I  realised that I was missing one python module needed for a setup.

To fix this I installed missing python packages and issue was fixed.


Configure Nginx

Edit file /etc/nginx/sites-available/mercurial.conf and add the following server definition:

The above settings will setup a new virtual host, where all traffic is redirected to the Mercurial FastCGI wrapper. It is important that you forward the PATH_INFO and REMOTE_USER variables. Mercurial will not work correctly without these.

Be sure that file /var/hg/hgusers contains all your Mercurial users with passwords, it can be created using htpasswd tool shipped with Apache.
Restart Nginx and try to to push pull.

In case you have a big push load you may get an 413 Request Entity Too Large error. Just add client_max_body_size 20M; to “server” part of config, like this:


One thing that changed was repositary path. Before it has /hg/ in path line

Now it become a full virtual host and changed to:

I have to reconfigure all my projects, but it is not a pain like it was with CVS.

Next thing I though about, I can move repositories under its own uid:gid and not run it under www-data, this can improve security.

Do not forget to include running spawn-fcgi into /etc/rc.local for automatically start on system boot.


My story is based on these links.


413 Request Entity Too Large

1 comment

  1. Hey A32, what made you change from Apache? I’m still struggling to get my setup working and am still using Apache. I am a little tempted to try this with Nginx, but at the same time I don’t changing just because I can’t fix my apache issue (push auth is denied).

Leave a Reply

Your email address will not be published.