在 Debian 上使用 stagit 和 Nginx 的简单 Git 服务器

2023 年 05 月 09 日
#Git #Linux #Nginx #Cloudflare

失败了

本来想在本文标题加个(失败了)的,但也不是全无所获,「几乎成功」了。大概是因为冷门吧,找到 stagit 与 OpenBSD 和 Apache Web 服务器的资料稍微多点,最终,我放弃了。

放弃可耻但有用!假以时日,我一定会卷土重来,完成它。如果看到这篇文章的您了解这些方面的知识,还恳请不惜赐教。

TL;DR

思路是这样的:我有个用于 Git 服务器的域名 git.xvo.es,Git 服务器使用 git-http-backend 提供 HTTP(S) 访问,fcgiwrap 将 CGI 程序转换为 FastCGI 进程,apache2-utils 里的 htpasswd 用于 HTTP 基本身份认证管理。

理想状况是:

  • 访问 https://git.xvo.es 是由 stagit 构建的静态存储库界面

  • 上面的存储库都可以被公开克隆,比如

    1
    
    git clone https://git.xvo.es/repoA.git
    
  • 涉及到需要更改存储库的操作需要经过 HTTP 基本认证

  • 本地推送提交到 Git 服务器后,Git Hooks 自动执行 stagit 构建静态存储库页面

记录

已经安装好了 git, nginx 和 stagit

软件包

1
2
sudo apt update \
&& sudo apt install -y fcgiwrap apache2-utils

新建用户

1
2
3
4
5
# 新建 git 用户
sudo adduser git

# 切换到 git 用户
su git

用户目录为 /home/git,各个存储库就像这样:

1
2
/home/git/repoA.git
/home/git/repoB.git

初始化

一个裸存储库初始化步骤如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
git config --global init.defaultBranch master
git init repoC.git --bare --shared

cd repoC.git
vim config
# 添加两行
[http]
    receivepack = true
# 添加结束
git update-server-info
touch git-daemon-export-ok

Nginx 配置

域名解析到服务器 IP,在 Cloudflare 上可以开启小黄云,SSL 证书设置完全或严格。使用 htpasswd 设置用于 HTTP 基本身份认证的密码凭据

1
sudo htpasswd -c /etc/nginx/.htpasswd <username>

假设 /var/www/git 存放 stagit 生成的静态网页

1
2
3
4
5
6
7
8
9
mkdir -p /var/www/git
sudo chown -R git:www-data /var/www/git
su git
cd /var/www/git

# stagit 个性化静态文件
wget https://github.com/DejavuMoe/stagit/raw/master/style.css
wget https://github.com/DejavuMoe/stagit/raw/master/logo.png
wget https://github.com/DejavuMoe/stagit/raw/master/favicon.png

编辑

1
sudo vim /etc/nginx/git-http-backend.conf

写入,注意 /home/git 是包含所有存储库的父级路径

1
2
3
4
5
6
7
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
fastcgi_param GIT_HTTP_EXPORT_ALL "";
fastcgi_param GIT_PROJECT_ROOT /home/git;
fastcgi_param PATH_INFO $1;
fastcgi_param REMOTE_USER $remote_user;

Nginx 配置文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
server {
    listen 80;
    listen [::]:80;
    server_name git.xvo.es;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name git.xvo.es;
  
    # 包含所有 Git 存储库的路径
    root /home/git;

    # 访问日志  
    access_log /var/log/nginx/git.xvo.es-access.log;
    error_log  /var/log/nginx/git.xvo.es-error.log;
    gzip off;
    # SSL 证书路径
    ssl_certificate /etc/nginx/cert/git.xvo.es.pem;
    ssl_certificate_key /etc/nginx/cert/git.xvo.es.key;

    location / {
        root /var/www/git;
        index index.html;
        try_files $uri $uri/ =404;
    }

    location ~ /git_read(/.*) {
        include git-http-backend.conf;
    }

    location ~ /git_write(/.*) {
        # HTTP 基本认证
        auth_basic "Require password to push to git.xvo.es:";
        auth_basic_user_file /etc/nginx/.htpasswd;
        include git-http-backend.conf;
    }
    # 路径捕获条件匹配
    location ~ (/.*) {
        if ($arg_service = git-receive-pack) {
            rewrite (/.*) /git_write$1 last;
        }
        if ($uri ~ ^/.*/git-receive-pack) {
            rewrite (/.*) /git_write$1 last;
        }
        if ($arg_service = git-upload-pack) {
            rewrite (/.*) /git_read$1 last;
        }
        if ($uri = ^/.*/git-receive-pack) {
            rewrite (/.*) /git_read$1 last;
        }
    }
}

确定没啥问题,可以启动了

1
2
sudo nginx -t
sudo nginx -s reload

尝试手动运行 stagit 和 stagit-index 生成静态存储库页面,打开 https://git.xvo.es 可以正常浏览静态存储库页面

使用

本地推送提交到 Git 服务器

1
2
3
4
git add .
git commit -m 'add something'
git remote add origin https://git.xvo.es/repoC.git
git push -u origin master  # 输入 HTTP 基本验证的用户名和密码

一些细节可能记不太清楚了,这并不是结束,不过,我现在要好好睡一觉,哈哈~

参考资料