Mercurial 付属の hgwebdir.fcgi を nginx で動かすメモ
CVS(やSubversion)をバージョン管理システムに使っていた頃はリポジトリの情報を見るのにViewVCを使っていましたが、ViewVCはMercurialをサポートしていません。Mercurial にはウェブ用の管理画面(hgweb/hgwebdir)が付属しているので、別のツールを使うニーズが少ないんでしょうね。
Mercurial のリポジトリ毎に対応する Redmine のプロジェクトが存在するので、そちらを見ればおおよその事は分かるのですが、Redmineのリポジトリブラウザはブランチを意識して作られていないので不便といえば不便です。
hgwebの事は Mercurial への移行を検討していたときにも調べていたんですが、Django, flup, setuptools, ez_setup.py, easy_install, .. とPythonに不慣れな人間にはなじみのない単語が続々と出てきたので、ちょっと敬遠していましたが、ちょっと時間が取れたのでチャレンジしてみました。
hgwebdir のセットアップをする前に必要なソフトウェアのインストールを行います。環境は OpenSolaris 2009.06 で、可能な限り pkg を使ってインストールしていきます。インストールしたのは以下のパッケージです。
SUNWPython26 SUNWPython26-extra SUNWpython26-setuptools
OpenSolaris 2009.06 のパッケージ管理システムにも Mercurial はありますが、バージョンが 1.1.2 と古く、クライアントの環境と合わないので、最新バージョンを easy_install からインストールします。
$ pfexec easy_install Mercurial $ hg --version Mercurial Distributed SCM (version 1.4.2) Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
次に flup が必要だそうなのでインストールします。
$ pfexec easy_install flup
hgwebdir を FastCGI で動作させるのにはいろいろな方法があるらしいのですが、Python特有のやり方はよく分からないので、lighttpd の spawn-fcgiを使いました。インストールは以下の通り簡単です。
$ wget http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz $ gzip -dc spawn-fcgi-1.6.3.tar.gz | tar xvf - $ cd pawn-fcgi-1.6.3 $ ./configure $ make $ pfexec make install
ここまででようやく下準備がおわりました。
hgwebdir.fcgi は /usr/demo/mercurial/hgwebdir.fcgi をコピーして使っています。
UTF-8 で表示するために、HGENCODING の設定を行う部分のコメントをはずしています。
os.environ["HGENCODING"] = "UTF-8"
hgweb.config は単純です。
[paths] / = /path/to/repos/*
これを以下のようなスクリプトで起動しています。
#!/bin/sh LANG=ja_JP.UTF-8 export LANG FCGI=/opt/local/bin/spawn-fcgi exec $FCGI -s /tmp/.fcgi_hgwebdir -G webserved -M 0660 ./hgwebdir.fcgi
nginx の設定ファイルは以下のようになりました。
初めて try_files を使ってみましたが、設定がとてもシンプルになりますね。
hgwebdir は PATH_INFO を利用してブラウズするリポジトリを探すようなので、その部分の置き換えにちょっと手を入れています。
server { listen 80; server_name hg.example.com; root /path/to/public; index index.html; access_log /var/log/nginx/hg-access.log main; location / { try_files $uri @hgweb; } location @hgweb { fastcgi_pass unix:/tmp/.fcgi_hgwebdir; fastcgi_read_timeout 5m; set $path_info ""; if ($fastcgi_script_name ~ "^/(.*)$") { set $path_info $1; } fastcgi_param PATH_INFO $path_info; } }