git を apache と連携して http アクセスできるようにする

git を apache と連携して http アクセスできるようにする

2024/01/05 00:00:00
Program
Git, Apache

前提 #

  • 環境は wsl2 ubuntu22.04 を想定。名前は Ubuntu-22.04
  • ubuntu22.04 は apache 環境は構築済みで http アクセスできること

設定 #

git.conf 作成 for apache #

「$ sudo emacs /etc/apache2/conf-available/git.conf」 でもいいが、virtualhost関連は sites-available で設定したほうがいいらしい

$ sudo emacs /etc/apache2/sites-available/git.conf

SetEnv GIT_PROJECT_ROOT /home/developer/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

<Location /git>
    Options ExecCGI
    AuthName "Git for HTTP"
    AuthType Basic
    AuthUserFile /home/developer/git/.htpasswd
    # AuthUserFile /home/developer/svn/.htpasswd  # <--- svn ユーザと共通化する場合
    Require valid-user
</Location>
  • サブドメインで公開の場合

    以下の例ではgit.test.net

    <VirtualHost *:80>
        ServerName git.test.net
        DocumentRoot /home/developer/git/repos
    
        SetEnv GIT_PROJECT_ROOT /home/developer/git/repos
        SetEnv GIT_HTTP_EXPORT_ALL
        ScriptAlias / /usr/lib/git-core/git-http-backend/
        <Location />
                  Options ExecCGI
                  AuthName "Git for HTTP"
                  AuthType Basic
                  AuthUserFile /home/developer/git/.htpasswd
                  Require valid-user
        </Location>
    
        <Directory /home/developer/git/repos>
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
    
    #    ErrorLog ${APACHE_LOG_DIR}/error.log
    #    CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
    
  • メモ

    Apache2の設定については、conf-availableとsites-availableの2つのディレクトリがありますが、
    それぞれ異なる目的で使用されます。
    conf-availableは、すべてのvhostsに影響を与えるグローバルな設定の断片を格納するためのものです。
    sites-availableは、完全なvhost定義を格納するためのもので、VirtualHostを分けて設定ファイルを置く場合は、
    sites-availableにファイルを追加し、sites-enabledからシンボリックリンクを貼る必要があります。
    あなたが提供した設定は、特定のパス(/git)に対する設定を含んでいるため、これは特定のサイトまたはvhostに
    関連する設定と見なすことができます。したがって、この設定はsites-availableディレクトリに配置するのが適切です。
    そして、そのサイトを有効にするためには、a2ensiteコマンドを使用してsites-enabledディレクトリにシンボリックリンクを作成します
    

追加した apache 用の git.conf を有効化 #

# $ sudo a2enconf git  # conf-available の場合
$ sudo a2ensite git
$ sudo apache2ctl configtest
Syntax OK

# 必要なモジュールも有効にしておく
$ sudo a2enmod cgi rewrite
Your MPM seems to be threaded. Selecting cgid instead of cgi.
Enabling module cgid.
Enabling module rewrite.
To activate the new configuration, you need to run:
  systemctl restart apache2

# apache 再設定 or 再起動
# $ sudo service apache2 reload  # こっちでもOK
$ sudo service apache2 restart

# メモ:apache site available 確認
$ sudo ls /etc/apache2/sites-enabled | grep git
git.conf
# メモ:apacheモジュール有効確認
$ sudo apachectl -M | grep rewrite
 rewrite_module (shared)

git リポジトリエリア作成 #

$ pwd
/home/developer
$ mkdir git
$ cd git

git リポジトリを作成するスクリプトも作成しておく
※git設定は ここ を参照

$ emacs mk_git_repository.sh

#!/bin/bash

# リポジトリ名が指定されていることを確認
if [ -z "$1" ]
then
  echo "リポジトリ名を指定してください。"
  exit 1
fi

# リポジトリが既に存在するか確認
if [ -d "$1" ]
then
  echo "指定したリポジトリは既に存在します。"
  exit 1
fi

# Gitリポジトリの作成
git init --bare --shared $1
if [ $? -ne 0 ]
then
  echo "Gitリポジトリの作成に失敗しました。"
  exit 1
fi

# ディレクトリに移動
cd $1
if [ $? -ne 0 ]
then
  echo "ディレクトリに移動できませんでした。"
  exit 1
fi

# # receive.packを有効にする
# git config receive.pack true
# if [ $? -ne 0 ]
# then
#   echo "receive.packの設定に失敗しました。"
#   exit 1
# fi

# # サーバー情報の更新
# git update-server-info
# if [ $? -ne 0 ]
# then
#   echo "サーバー情報の更新に失敗しました。"
#   exit 1
# fi

# 所有者の変更
# sudo chown -R www-data:www-data .
# sudo chown -R www-data:www-data .
sudo chgrp -R www-data .
if [ $? -ne 0 ]
then
  echo "所有者の変更に失敗しました。"
  exit 1
fi

echo "Gitリポジトリの作成が完了しました。"

ファイルダウンロード

作成した mk_git_repository.sh に権限を追加

$ chmod +x mk_git_repository.sh

git リポジトリエリアに権限付与 #

作成したgitリポジトリエリアに権限を追加

$ cd ..
$ pwd
/home/developer

$ sudo chgrp -R www-data git

git リポジトリを作成 #

ここでは test.git リポジトリを作成する

# git リポジトリ追加
$ cd git
$ ./mk_git_repository.sh test.git
Initialized empty shared Git repository in /home/developer/git/test.git/
Gitリポジトリの作成が完了しました。

# 念のため
$ sudo systemctl restart apache2

git ユーザ作成(.htpasswdファイル作成) #

  • ※ -c オプションは .htpasswd ファイルを作成するオプションコマンド。すでに .htpasswd ファイルが存在していて、ユーザを追加する場合は必要ない。-c つけると .htpasswd ファイルが再生成されるため、追加済みユーザがすべて削除されるので注意
  • ※ htpasswd コマンドが存在しない場合、$ sudo apt install apache2-utils でインストール可能
$ cd git
$ htpasswd -c .htpasswd oya
  New password:
  Re-type new password:
  Adding password for user oya

git ユーザ追加 #

$ cd git
$ htpasswd .htpasswd oya2
  New password:
  Re-type new password:
  Adding password for user oya2

内部からアクセスできるか確認 #

$ git clone http://localhost/git/test.git
Cloning into 'test'...
warning: You appear to have cloned an empty repository.
# ↑の通り、空っぽなんで empty 表示される。

外部PCからアクセスできるようにする #

wsl2 ubuntu22.04 の場合、ポートフォワード設定で対応可能となるが、、、
面倒なのが、wsl2 ubuntu22.04 が起動の度にipアドレスが変更されるため、手動で毎回ipアドレスの確認が必要となる。
面倒するぎるので、以下のスクリプト(set_wsl2_ip.ps1)で対応したが、きっともっといい対応方法があると思われる。
※wsl2 udpate するとホストとゲストのIP空間を共通にできたりできる様子。だが、windows11のみのようなので現状はこのスクリプトで対応するしかなと思ってる。。。

  • 作成した set_wsl2_ip.ps1 は windows10 ホストのスタートアップに登録しておくことで外部PCからのアクセスが有効になる
  • windows10 ホストの ip アドレスは 172.17.10.xx としている
  • ここでは wsl -d Ubuntu-22.04 として強制起動もしているので注意

以下に set_wsl2_ip.ps1 ファイルの内容を示す。
※crlf で保存すること。 lf だと実行できない。文字コードはsjisでもutf8でも実行できそうだが、日本語版windowsだとsjisにしておいたほうが便利かもしれない

$ emacs set_wsl2_ip.ps1

# PowerShellスクリプト

# 以下でネットワーク一覧が取得できる
#  $ Get-NetAdapter | Format-Table -Property Name, Status, MacAddress, LinkSpeed
# 以下で上記コマンドで取得したネットワーク一覧のindex(0始まり)値(最後の[])に代入すると対応したアドレスが取得できる
#  $ ([system.net.dns]::GetHostAddresses((hostname)) | where {$_.AddressFamily -eq "InterNetwork"} | select -ExpandProperty IPAddressToString)[0]
# 以下でネットワーク名でアドレスが取得できる
#  $ (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -eq "ネットワーク名" -and $_.AddressState -eq "Preferred" }).IPAddress
# 結論としては面倒なんで固定でipを設定しておく

# 管理者権限で実行されていない場合、管理者権限で同じスクリプト(ps1ファイル)を実行しなおす設定
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    $arguments = "& '" + $myinvocation.mycommand.definition + "'"
    Start-Process powershell -Verb runAs -ArgumentList $arguments
    Break
}

$GuestOS="Ubuntu-22.04"
$HostOS_IP="172.17.10.153"

# 念のため前回のポートフォワード設定を破棄しておく
netsh.exe interface portproxy delete v4tov4 listenport=80 listenaddress=$HostOS_IP
# 今回のwsl2 ubuntu22.04のipアドレス取得
#  以下でも取得できるっぽい
#  $ wsl -d $GuestOS -e bash -c "ip address show eth0 | grep 'inet ' | awk '{split(\$2,ipa,\"/\");print ipa[1]}'"
$WSL2_IP=(wsl -d $GuestOS -e sh -c "ip -4 -o addr show eth0 | cut -d' ' -f7 | cut -d/ -f1").Trim()
# 今回のポートフォワード設定
netsh.exe interface portproxy add v4tov4 listenaddress=$HostOS_IP listenport=80 connectaddress=$WSL2_IP connectport=80
# 今回のポートフォワード設定確認
netsh.exe interface portproxy show v4tov4

echo "HostOS_IP:[$HostOS_IP]"
echo "The IP address of WSL2 $GuestOS is set to [$WSL2_IP]. press any key..."
wsl -d $GuestOS
pause

ファイルダウンロード

実行には権限付与が必要
管理者権限でpowershellを起動して以下を実施

# 実行ポリシーを有効にする
$ Set-ExecutionPolicy RemoteSigned
# 再度、実行ポリシーを無効にする
$ Set-ExecutionPolicy Restricted

単一コマンドとして実行するならpowershellを起動して以下を実施
※ 単純に set_wsl2_ip.ps1 を実行しても、ps1ファイルに初期で紐づく「メモ帳」が開くので注意
※ set_wsl2_ip.ps1 ダブルクリック等を実行させたい場合、ps1ファイル紐づきをpowershell(C:\Windows\System32\WindowsPowerShell\v1.0)に変更する必要がある

$ PowerShell -ExecutionPolicy Bypass -File .\set_wsl2_ip.ps1

スタートアップに登録する場合 ファイル名を指定して実行で「shell:startup」を指定。その後、表示されたディレクトリに以下のショートカットを作成する

$ PowerShell -ExecutionPolicy Bypass -File "実行したいps1ファイルのフルパス"

上記、フォワード設定が完了したらば、外部PC等からclone実験する
作成した set_wsl2_ip.ps1 を実行し以下のコマンドを実行しアクセスできるか確認しておく

$ git clone http://172.17.10.xx/git/test.git
Cloning into 'test'...
warning: You appear to have cloned an empty repository.
# ↑の通り、空っぽなんで empty 表示される。

gitweb 設定 #

/gitweb でアクセスする #

gitweb インストールする

$ sudo apt install gitweb

gitweb.conf 修正する

sudo emacs /etc/gitweb.conf

# path to git projects (<project>.git)
$projectroot = "/home/developer/git";  # <--- ここ変更
...

apache 用 git.conf 修正する

$ sudo emacs /etc/apache2/sites-available/git.conf

SetEnv GIT_PROJECT_ROOT /home/developer/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

<Location /git>
    Options ExecCGI
    AuthName "Git for HTTP"
    AuthType Basic
    AuthUserFile /home/developer/git/.htpasswd
    # AuthUserFile /home/developer/svn/.htpasswd  # <--- svn ユーザと共通化する場合
    Require valid-user
</Location>

# 以下追加
Alias /gitweb /usr/share/gitweb

<Directory /usr/share/gitweb>
    Options +FollowSymLinks +ExecCGI
    AddHandler cgi-script .cgi
    # # 必要に応じてアクセス許可 IP 追記
    # Require ip 127.0.0.1 10.0.0.0/24
</Directory>

apache 再起動する

$ sudo systemctl restart apache2 

再起動後、ブラウザで http://172.17.10.xx/gitweb にアクセスするとリポジトリ一覧が表示される

/gitweb を /git/ でアクセスできるようにする #

gitweb インストールする

$ sudo apt install gitweb

gitweb.conf 修正する

sudo emacs /etc/gitweb.conf

# path to git projects (<project>.git)
$projectroot = "/home/developer/git";  # <--- ここ変更
...

apache 用 git.conf 修正する

$ sudo emacs /etc/apache2/sites-available/git.conf

SetEnv GIT_PROJECT_ROOT /home/developer/git
SetEnv GIT_HTTP_EXPORT_ALL

Alias /git/static/ /usr/share/gitweb/static/

ScriptAliasMatch \
    "(?x)^/git/(.*/(HEAD | \
                info/refs | \
                objects/(info/[^/]+ | \
                         [0-9a-f]{2}/[0-9a-f]{38} | \
                         pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                git-(upload|receive)-pack))$" \
    /usr/lib/git-core/git-http-backend/$1

ScriptAlias /git/ /usr/share/gitweb/

<Location /git>
    Options ExecCGI
    AuthName "Git for HTTP"
    AuthType Basic
    AuthUserFile /home/developer/git/.htpasswd
    # AuthUserFile /home/developer/svn/.htpasswd  # <--- svn ユーザと共通化する場合
    Require valid-user
</Location>

<Directory /usr/share/gitweb/static>
    Options FollowSymLinks
    AllowOverride None
</Directory>

apache 再起動する

$ sudo systemctl restart apache2 

再起動後、ブラウザで http://172.17.10.xx/git/ にアクセスするとリポジトリ一覧が表示される

  • メモ
    Alias /git/static/ /usr/share/gitweb/static/ の行の他のScriptAlias設定より前にもっていかないと重複しているという警告がでる。
    ※そもそも/gitwebと/gitを共用にする必要もない気がする。やりたい人だけの設定かも。。。
    $ sudo apachectl configtest
    [Thu Jan 11 11:23:28.773982 2024] [alias:warn] [pid 8636:tid 140307644381056] AH00671: The Alias directive in /etc/apache2/sites-enabled/git.conf at line 13 will probably never match because it overlaps an earlier ScriptAlias.
    Syntax OK
    

description 設定 #

ブラウザで特定のリポジトリを閲覧すると以下のようなdescriiptionがないという文言が表示される。

この対象のリポジトリの description ファイルを修正すればいいだけ

$ cd git/test.git
$ pwd
/home/developer/git/test.git
$ emacs description
test.git  #<-- 適当に test.git としておく

参考URL #