diff options
author | Yuuta Liang <yuuta@yuuta.moe> | 2023-11-07 13:50:10 +0800 |
---|---|---|
committer | Yuuta Liang <yuuta@yuuta.moe> | 2023-11-07 13:50:10 +0800 |
commit | f27c5ec67350af0dd18ba6f8b98f73d9513a1983 (patch) | |
tree | 674f8179af6fa1067a33afb6e62a7c176e3e0afa | |
parent | 81043b5990630b71375e250102eebe22a989fb4b (diff) | |
download | kb-f27c5ec67350af0dd18ba6f8b98f73d9513a1983.tar kb-f27c5ec67350af0dd18ba6f8b98f73d9513a1983.tar.gz kb-f27c5ec67350af0dd18ba6f8b98f73d9513a1983.tar.bz2 kb-f27c5ec67350af0dd18ba6f8b98f73d9513a1983.zip |
Finish up git server
-rw-r--r-- | docs/sysadmin/misc/git_server.md | 160 |
1 files changed, 159 insertions, 1 deletions
diff --git a/docs/sysadmin/misc/git_server.md b/docs/sysadmin/misc/git_server.md index 3dcc080..8c680bc 100644 --- a/docs/sysadmin/misc/git_server.md +++ b/docs/sysadmin/misc/git_server.md @@ -1,8 +1,166 @@ # Git Server +Down to the minimum, a git "server" could just be a bare repo located somewhere +in the filesystem: + +```shell +$ git init --bare repo.git +$ ls repo.git/ +$ git clone repo.git +$ ls repo/ +``` + +Thus it's possible to remotely access it using NFS or SSH. + +Since the repo is just a directory on the filesystem, it uses the filesystem +permissions. It's not supported for multiple users to be able to write to the +bare repository, and only the owner can do so. Also, there're no permission +control or branch protection because the owner could easily override things +in that directory. + +Thus, advanced permission manage solutions exist, like Gitea, GitLab, GitHub, +or if you prefer something simpler, gitolite. + +Gitea, GitLab, and GitHub are complete Git solutions that not only does bare +Git repo management, but also integrates permission control, web browsing, CI / +CD, and lots more. They are also easier (somehow) to setup, and may be suitable +and easy for more people (especially for those prefer pull requests over email +patches). + +## Git -> HTTP Interface + +It's awesome to have a HTTP interface that allows users to preview the repo +without cloning it alltogether. Besides complicated all-in-one solutions like +GitLab, simple programs exist, notably gitweb and cgit. + +It is worth noting that the web interface has nothing todo with HTTP cloning. +HTTP cloning is a complete different protocol using HTTP, and it is handled +using a different program. + +gitweb is the default web interface shipped with git. I used it in the past but +quickly replaced it with cgit for just a little more fancy features. + +cgit is developed by Jason A. Donenfeld (the person who developed WireGuard), +and it is actively maintained. Its git repo is at +[git.zx2c4.com/cgit](https://git.zx2c4.com/cgit/). + +Both gitweb and cgit are FastCGI programs. Make sure you have a basic +understanding of how FastCGI works before proceeding. + +And here is my Nginx configuration for cgit: + +```nginx +root /usr/share/webapps/cgit/; +location ~* ^.+\.(css)$ { + root /usr/share/webapps/cgit/; +} +location /robots.txt { + root /usr/share/webapps/cgit/; +} +location ~* ^.+\.(png|ico)$ { + root /srv/http/cgit/; +} +location / { + include fastcgi_params; + index cgit.cgi; + fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi; + fastcgi_param PATH_INFO $uri; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + fastcgi_pass unix:/run/fcgiwrap.sock; +} +``` + +The configuration is pretty straightforward and self-explanatory. Configuring +HTTP rewrite could be a little bit troublesome, though. In my configuration, I +set `virtual-root=/` in `cgitrc(5)` to solve path issues. + +The cgit configuration file `cgitrc(5)` is at `/etc/cgitrc`, and it is also +pretty straightforward. Some key points in my setup are: + +``` +# Solve path issues +virtual-root=/ + +# Enable source highlighting. Slow +source-filter=/usr/lib/cgit/filters/syntax-highlighting.py + +# Enable README rendering. +about-filter=/usr/lib/cgit/filters/about-formatting.sh +readme=:README.md # Enable readme preview. Copied from cgitrc(5) +# Append more readme=: here. + +# Automatically load repos from the path. +scan-path=/srv/git/ + +clone-prefix=https://git.yuuta.moe +``` + +cgit itself does not do authentication. My friend wrote a tool called +[cgit-simple-authentication](https://github.com/KunoiSayami/cgit-simple-authentication) +which may sound interesting to you. + +## HTTP Cloning + +HTTP cloning is handled by `git-http-backend`, a FastCGI application shipped +with git. Running it doesn't require any configuration except a set of +well-defined HTTP path regular expressions, so the web server works fine with +both HTTP cloning and cgit in the same domain. Here's a Nginx configuration I +got from the Internet: + +```nginx +location ~ ^.*\.git/objects/([0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+.(pack|idx))$ { + root /srv/git/; +} +location ~ ^.*\.git/(HEAD|info/refs|objects/info/.*|git-(upload|receive)-pack)$ { + root /srv/git/; + fastcgi_pass unix:/run/fcgiwrap.sock; + fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; + fastcgi_param PATH_INFO $uri; + fastcgi_param GIT_PROJECT_ROOT $document_root; + fastcgi_param GIT_HTTP_EXPORT_ALL ""; + fastcgi_param REMOTE_USER $remote_user; + include fastcgi_params; +} +``` + +In this configuration: + +* Repos must be suffixed `.git`. Without `.git` it will be directed to cgit. +* The path of git repos are `/srv/git`, the same as `scan-path` in `cgitrc(5)`. + ## Hooks -Script to run as the current user during certain actions (e.g., after pushing). +Script to run as the current user during certain actions (e.g., after pushing). +They are located in bare repo `hooks/*`. + +## Post receive + +The hook to be executed after each hook. I'm using a simple (and ugly) script +to build my website. It is absolutely better to use some kinda solutions like +Jenkins. + +```shell +#!/bin/sh +set -e +GITDIR="$(pwd)" +BUILDDIR="/tmp/build_kb_$(date +%s)" +BRANCH=$(cat | sed -e "s/[a-z0-9]* [a-z0-9]* refs\/heads\/\(.*\)/\1/g") +if test "$BRANCH" != "master"; then + exit 0 +fi +echo "Deploying ..." +git clone --recurse-submodules -q $GITDIR $BUILDDIR +cd $BUILDDIR +set +e +unset GIT_DIR +make +set -e + +cd $GITDIR +rsync -r --delete $BUILDDIR/site/ /srv/http/kb/ +rm -rf $BUILDDIR +``` ### Environment variables |