Mercurial + Nginx

Step 1: install software

# portmaster www/nginx devel/mercurial devel/py-mercurialserver www/fcgiwrap

We need www/fcgiwrap because nginx doesn't support cgi, but it does support fastcgi

Step 2: configure mercurial-server

HINT: by default mercurial-server will use /usr/local/hg/ directory. If you want to change that:

# pw usermod hg -h /srv/hg

I will use /srv/hg/ to store mercurial-server data.

Since we'll need ssh key let's generate one

# ssh-keygen

and save it to ssh-key (private) and ssh-key.pub (public) Make sure you can copy keys securely. You will need pub key on server, and private key on your desktop pc (or whatever you use)

Now become hg user and initialize mercurial-server (hg's home must be writeable by hg) Code:

# mkdir /usr/local/etc/mercurialserver/keys/root/homepc
# cp /path/to/ssh-key.pub /usr/local/etc/mercurialserver/keys/root/homepc/
# su -l hg -c tcsh
$ refresh-auth
$ exit
Step 2: Configure /etc/rc.conf
This part is trivial
Code:
fcgiwrap_enable="YES"
fcgiwrap_user="www"
nginx_enable="YES"
sshd_enable="YES"

Don't forget to configure your ssh to use public/private key authorization

Step 3: Configure nginx

to your /usr/local/etc/nginx/nginx.conf add host config Code:

server {
listen 80;
server_name hg.example.com;
location ~ / {
fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap.sock;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SCRIPT_FILENAME /srv/www/example.com/hg/hgweb.cgi;
include fastcgi_params;
}
}

here /srv/www/example.com/hg/hgweb.cgi is cgi script, that we will modify later

P.S. This is just part of nginx.conf…. rest, is up to you… this is what you need to get hgweb work in nginx

Step 4: Configure hgweb

/srv/www/example.com/hg/hgweb.cgi is modified copy of /usr/local/share/mercurial/www/hgweb.cgi Code:

#!/usr/bin/env python
#
# An example hgweb CGI script, edit as necessary
# See also http://mercurial.selenic.com/wiki/PublishingRepositories
# Path to repo or hgweb config to serve (see 'hg help hgweb')
config = "/srv/www/example.com/hg/hgweb.config"
# Uncomment and adjust if Mercurial is not installed system-wide:
#import sys; sys.path.insert(0, "/path/to/python/lib")
# Uncomment to send python tracebacks to the browser if an error occurs:
#import cgitb; cgitb.enable()
from mercurial import demandimport; demandimport.enable()
from mercurial.hgweb import hgweb, wsgicgi
application = hgweb(config)
wsgicgi.launch(application)

you need to adjust config, which points to config file for hgweb

/srv/www/example.com/hg/hgweb.config Code:

[collections]
/srv/hg/repos/pub = /srv/hg/repos/pub
[web]
#contact = aldis@bsdroot.lv
#description = Mercurial repositories @ bsdroot.lv
style = gitweb
#allow_push = *
#push_ssl = false
allow_archive = bz2 gz
#base = repos
baseurl =

This is my own hgweb.config from my server More details: http://mercurial.selenic.com/wiki/HgWebDirStepByStep NOTE: make sure /srv/hg/repos/pub is www group readable

I use collections… that's why I didn't specify contact and description, here. If you want to have contact and description for your projects, you will have to manually place .hg/hgrc in your repositories on server. for example Code:

[web]
contact = me@example.com
description = some description

If you don't do that, then it will be "unknown" (or something like that) If you specify contact and description in hgweb.config these settings will become default for all repositories, that don't have .hg/hgrc NOTE: you can also modify some other options as well (in .hg/hgrc)

Step 5: manage users

On your desktop create hgadmin repository for users, that can only read/write repos make dir keys/users/USERNAME, replace USENAME of actual username of user, whose keys will be in this directory for other admins keys/root/USERNAME…. once you're done configuring hgadmin, cone it (for the first time, later just push it) to ssh:\/\/hg.example.com/hgadmin

$ ht clone . ssh://hg.example.com/hgadmin