lighttpd で git レポジトリを公開

Pocket

コード書くことがあるなら、バージョン管理ソフトを使ったことはありますよね?

個人で作ってるプログラムなどはホームサーバの Subversion で管理してました
apache + subversion のよくあるパターンを使ってました

この度、ホームサーバのウェブサーバを勢いで apache から lighttpd に変更しました
Subversion とかの連携とか何も考えずやってしまったんですよね

しょうがないので、lighttpd 上で Subversion のレポジトリが公開できるか見てみると・・・
プロキシ立てて、subversion は apache で動かすという記事を発見!
せっかく lighttpd にした意味がない!
lighttpd だけで動かせそうなバージョン管理ソフトないか探していると、git が動くっぽい

ということで、lighttpd 上で git レポジトリ公開するまでの旅(1.5d)が始まるのでした

<基本構成>
ディストリビューションは Momonga Linux 7 です。多分、Fedora でも設定同じだと思います。
git と lighttpd は RPM のモノをそのまま使いました
そのままなので、 lighttpd のユーザーとグループは lighttpd:lighttpd です
</基本構成>

<git レポジトリの作成>
git のレポジトリは、/opt/git をgit のレポジトリルートとして作成します
今回は hoge.git を作成します

$ sudo mkdir -p /opt/git/hoge.git
$ cd /opt/git/hoge.git
$ sudo git --bare init
$ sudo chown -R lighttpd.lighttpd /opt/git

そのままだとサーバーに push してもサーバーのレポジトリの情報が更新されない
情報を反映させるためには下記コマンドを実行する必要がある

$ git update-server-info 

しかし、更新するたびに毎回サーバーに入って コマンドを実行するのは面倒である
/opt/git/hoge.git/hooks に post-update.sample というファイルがあるのでコピーする

$ cd /opt/git/hoge.git/hooks
# cp -a post-update.sample post-update

post-update の中身を見てもらえばわかるが、 git update-server-info を実行している
</git レポジトリの作成>

<lighttpd.conf の設定>
git を使うのだが、alias、setenvを使うので /etc/lighttpd/lighttpd.conf の server.modules に
mod_alias と mod_setenv を追加する
git レポジトリを公開するのに認証を使うので mod_auth も追加する

server.modules = (
  "mod_alias",
  "mod_auth",
  "mod_setenv" )

git で HTTP ステータス 100 を使うが、バージョンが 1.5 未満の lighttpd だと 100 を認識できずに 417 のステータスコードが出るかもしれない
その場合は、以下の設定を lighttpd.conf に追加する

server.reject-expect-100-with-417 = "disable"

これで結構苦労したが、こちらを参考にした
これを記述してないとレポジトリにプッシュすると git では return code 22 が返ってくる
そして、アクセスログには 417 のステータスコードのアクセスが出る

これを設定して、ステータスコードが 404 になった場合は違うことが原因だと思う
</lighttpd.conf の設定>

<git.conf の作成>
lighttpd に git レポジトリ用に設定を追加する
今回は https を使うことを前提に設定ファイルを作成する

$SERVER["socket"] == ":443" {
  ssl.engine = "enable"
  ssl.pemfile = "/etc/lighttpd/ssl.pem"
  server.name = "git.example.jp"
  server.document-root = "/var/www/html"

  alias.url = (
    "/git" => "/usr/libexec/git-core/git-http-backend"
  )

  $HTTP["url"] =~ "^/git" {
    cgi.assign = ("" => "")
    setenv.add-environment = (
      "GIT_PROJECT_ROOT" => "/opt/git",
      "GIT_HTTP_EXPORT_ALL" => ""
    )
  }

  auth.backend = "htdigest"
  auth.backend.htdigest.userfile = "/etc/lighttpd/lighttpd.user.htdigest"
  auth.require = (
    "/git" =>
    (
      "method" => "digest",
      "realm" => "git",
      "require" => "valid-user"
    )
  )
}

ssl.pem は下記コマンドで多分作れると思う
ここでは詳しく述べない

$ cd /etc/lighttpd
# openssl req -new -x509 -keyout ssl.pem -out ssl.pem -days 365 -nodes

上の設定だと認証用のファイルもつくらないといけない
hoge ユーザーを作る設定は下記コマンドで

# htdigest -c /etc/lighttpd/lighttpd.user.htdigest "git" hoge

</git.conf の作成>

<レポジトリを取得してみる>
クライアントマシンで作ったレポジトリを取得してみる
すると、下記のようなメッセージが出て上手くいかないかもしれない

$ git clone https://git.example.jp/git/hoge.git
error: Peer certificate cannot be authenticated with given CA certificates while accessing https://git.example.jp/git/hoge.git/info/refs
fatal: HTTP request failed

手作り認証局なので SSL のエラーになってしまう

その場合は、クライアントで下記コマンドで SSL のチェックをしないようにしてしまう
もちろん自己責任ですよ

$ git config --global http.sslVerify false

あともう一つ refs 関係でエラーが出たような・・・

$ git clone https://git.example.jp/git/hoge.git
Cloning info 'config'...
fatal: https://git.example.jp/git/hoge.git/info/refs not found: did you run git update-server-info on the server?

と表示されたら、サーバーで言われたとおり git update-server-info を実行します

$ cd /opt/git/hoge.git
# sudo su lighttpd -c "git update-server-info"

ここまでで clone などの取得はできる?と思います
</レポジトリを取得してみる>

<ハマったこと>
最初、clone と push できるようにしてから
認証をかけるようにしようとした

どうやら、 git-http-backend は anonymous だと デフォルトだと push 出来ない
下記のようなエラーが表示される

$ git push origin master
error: Cannot access URL https://git.example.jp/git/hoge.git/, return code 22
fatal: git-http-push failed

アクセスログには下記のようなエラーが。

"PROPFIND /git/hoge.git/ HTTP/1.1" 404

man を見たら /opt/git/hoge.git/config に書いておけば anonymous でも書き込みできる

[http]
  receivepack = true

そんなことはせずに git レポジトリに認証設定までやってからテストしましょう
</ハマったこと>

コメントを残す