今風にUbuntuにGitの公開サーバを立てた

外向きのgitサーバが欲しいなぁと思って立ててみた。

* Ubuntu 12.04 (後に14.04へうｐ)
* Sart HTTP
* Apacheのユーザがwww (Ubuntuのデフォルトはwww-data)
* Apache httpdのバージョンが2.2 (最新だと2.4でconfファイル名がちょっと違ったり、deny from allが違ったり)

# 1. GitにはWebDavを使わない方が良いらしい
> WebDAVを通じてホストすると遅い
> WevDAVを通じてホストするとサーバサイドフックが起動しない
> http://blog.anatoo.jp/entry/20120619/1340033935

Subversionの時はsvnservせずにWebDavしようぜ、っていう流れだったからGitでもWebDavで良いのかと思いきやどうやら罠らしい。

# 2. 最近の流行はSmart HTTPらしい
ググってるとどうやらSmart HTTPを利用するのが今風らしい。

> ２つ方法があって、最初からssh経由でホストするか、Smart HTTPを導入するかのどちらかだ。
> http://blog.anatoo.jp/entry/20120619/1340033935

> うわぁぁぁ。　最初からこっちにしてればよかった。。ってくらい分かりやすい。
> いや、　なんていうのかな、分かりやすいんだよね。　とても。
> http://altarf.net/computer/server_tips/1446

> CGI の判断が「このクライアントは Smart HTTP に対応している」だった場合は Smart HTTP が使われ、そうでなかった場合はリードオンリー（“dumb”）にフォールバックします（
> http://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-Smart-HTTP

<!-- 幸いな事にうちは、フロントエンドにリバースプロキシを設置していてサービスごとにhttp通信を振り分けしてるので、git.example.comにアクセスがあった場合には内部のgit用のSmart HTTPに振ってあげれば良いかな、と。 -->

# 3. インストール
Smart HTTP用にgitwebを入れる。

```
sudo aptitude install git apache22 gitweb
```

http://www.tikalk.com/devops/setup-git-gitweb-git-http-backend-smart-http-ubuntu-1204/

Ubuntuではgitパッケージだけだと公開に必要なgit-http-backendが入らないらしいのでGitwebも入れておいた
(実際のgitwebの機能はオフ)

# 4. Apache用のconfを書く
```conf:/etc/apache2/sites-available/git
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName git.example.com
        DocumentRoot /mnt/git_repositories/

        SetEnv GIT_PROJECT_ROOT /mnt/git_repositories/
        SetEnv GIT_HTTP_EXPORT_ALL
        ScriptAlias /git /usr/lib/git-core/git-http-backend

        <Location />
            Order deny,allow
            Deny from all
            AuthType Basic
            AuthName "Git Access"
            AuthUserFile /mnt/git_repositories/.htpasswd
            AuthGroupFile /dev/null
            Require valid-user
        </Location>
        ErrorLog ${APACHE_LOG_DIR}/error_git.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
#        LogLevel debug

        CustomLog ${APACHE_LOG_DIR}/access_git.log combined
</VirtualHost>
```
htpasswdファイルを作っておく
```
shell> sudo sh -c 'htpasswd -nb user password > /mnt/git_repositories/.htpassed'
shell> sudo chmod 600 /mnt/git_repositories/.htpassed
shell> sudo chown www:www /mnt/git_repositories/.htpassed
```

apacheの再起動 (reloadでもおｋ)
```
shell> sudo a2ensite git
shell> sudo service apache2 restart
```

# 5. Gitのテスト用リポジトリの初期化
```
shell> sudo mkdir -p /mnt/git_repositories/sandbox.git
shell> cd /mnt/git_repositories/sandbox.git
shell> sudo git --bare init --shared=true
shell> sudo git update-server-info
shell> sudo chown -R www:www /mnt/git_repositories`
```
# 6. 他のホストからGitのテスト
```
shell> git clone http://git.example.com/git/sandbox.git ./sandbox
shell> cd sandbox; touch hoge; git add hoge; git commit -m 'first commit'
shell> git push
```

うまくいきました。

ココまでで結構上等なんですけど、もう少しやってみました。

# 7. LDAP認証を入れてみた
```
conf:/etc/apache2/sites-available/git
      <Directory />
          Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
          AllowOverride All
          Deny from all
          AuthType Basic
          AuthName "Private"
          AuthBasicProvider ldap
          AuthzLDAPAuthoritative on
          AuthLDAPURL ldap://ldap.example.com/ou=people,dc=example,dc=com?uid
          Satisfy all
          require ldap-user username
       </Directory>
```

ばっちりいけました。

# 8. その他失敗談、バッドノウハウ
実際にはこんなにスムーズに行かなくて、色々と試してた。
## 8.1. ロギング
うまく行かない時の基本は

* 詳細にログを取る
* エラーメッセージでググる
* 人に聞く

に尽きます。
残念ながら人に聞く、というのはできる人とできない人がいるので(僕はできない人)、ログを眺めるかググるか。
ここではapacheの
```        LogLevel debug```
を有効にしてひたすらログを眺めました。
screenでtail -fを駆使するとすごく良いです。
## 8.2. ワンライナーでの試験
今回のようなHTTPでの外向きGitサーバを立てる、というのはwebサーバを立てるということだったりするので、
conf編集 -> サービス再起動 -> 試験
をひたすら繰り返すことに。
ワンライナーでこれらをできるようにしておくと吉。
```
shell> sudo emacs /etec/apache2/sites-available/git; sudo service apche2 restart; wget -O - http://git.example.com/git/hoge
```
## 8.3 ScriptAliasのパス
今回はVirtualHostとして git.example.com を立てることになったんだけれども、そうすると各リポジトリへのアクセスは
```http://git.example.com/hoge```
のように直下に置きたかったんですね。
そうなるとScriptAliasで / へのアクセスを /usr/lib/git-core/git-http-backend にアクセスするようにすれば行けるのかな、と思ったんだけれどもダメだった。
(git-http-backendに渡される際にapacheの環境変数で/などのパス、PATH_INFOがあるんだけれどこれが空になってしまって、その際にはうまく動かないらしい。なので必ず /git のように設定しなければダメでした。(どなたか解決策や情報があれば是非))

## 8.4 Apache2.4へのアップグレード
この後にApacheのバージョンアップ
変更点は下記。

``` conf:/etc/apache2/sites-available/git.conf
     <Directory />
          # Options FollowSymLinks

          Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
          AllowOverride All
          AuthType Basic
          AuthName "Private"
          AuthBasicProvider ldap
          AuthLDAPURL ldap://ldap.example.com/ou=people,dc=example,dc=com?uid
          Satisfy all
          require ldap-user username
       </Directory>
```
sites-availableの以下のファイル名に.confを付けないとエラーになるので注意。
AuthzLDAPAuthoritativeが不要になる。