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/hgweb.config
[collections] repos/ = repos/
/var/hg/hgwebdir.cgi - For Apache CGI support
/var/hg/hguser - for user passwords in htpasswd format
Apache configuration was the following
ScriptAliasMatch ^/hg(.*) /var/hg/hgwebdir.cgi$1 <Directory /var/hg> Options ExecCGI FollowSymLinks AllowOverride None </Directory>
<Location /hg> AuthType Basic AuthName "Mercurial repositories" AuthUserFile /var/hg/hgusers Require valid-user </Location>
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
copy /usr/share/doc/mercurial-common/examples/hgwebdir.fcgi /var/hg chmod +x /var/hg/hgwebdir.fcgi
Or grab the file here
wget http://selenic.com/repo/hg/raw-file/tip/contrib/hgwebdir.fcgi
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
#apt-get install spawn-fcgi
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:
#spawn-fcgi -u www-data -g www-data -s /tmp/mercurial.sock -d /var/hg/ -- /var/hg/hgwebdir.fcgi
At first start I've run into the problem
spawn-fcgi: child exited with: 1
After running with "-n" switch to see debug output, I realised that I was missing one python module needed for a setup.
Traceback (most recent call last): File "/var/hg/hgwebdir.fcgi", line 25, in from flup.server.fcgi import WSGIServer File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 106, in _demandimport mod = _origimport(name, globals, locals) ImportError: No module named flup.server.fcgi
To fix this I installed missing python packages and issue was fixed.
#apt-get install python-flup
Configure Nginx
Edit file /etc/nginx/sites-available/mercurial.conf and add the following server definition:
server {
listen 80;
server_name YOUR_MERCURIAL_DOMAIN;
location / {
auth_basic "Secure Login";
auth_basic_user_file /var/hg/hgusers;
include fastcgi_params;
fastcgi_param PATH_INFO $uri;
fastcgi_param REMOTE_USER $remote_user;
fastcgi_intercept_errors on;
fastcgi_pass unix:/tmp/mercurial.sock;
}
}
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:
server {
listen 80;
server_name YOUR_MERCURIAL_DOMAIN;
client_max_body_size 20M;
Misc
One thing that changed was repositary path. Before it has /hg/ in path line
http://a32.me/hg/project1
Now it become a full virtual host and changed to:
http://hg.a32.me/project1
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.
Links
My story is based on these links.
- http://www.opennet.ru/base/dev/mercurial_http.txt.html
- http://geeksharp.com/2010/01/20/mercurial-web-with-fastcgi-nginx/
- http://fosswire.com/post/2009/08/hosting-mercurial-repositories-with-nginx/
- http://www.softwareprojects.com/resources/programming/t-how-to-serve-mercurial-hg-repository-over-nginx-1856.html
- http://www.dikant.de/2009/07/29/running-mercurial-with-fastcgi-in-nginx/
English
Русский
December 11th, 2011 - 05:53
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).