summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuuta Liang <yuuta@yuuta.moe>2023-11-07 13:50:10 +0800
committerYuuta Liang <yuuta@yuuta.moe>2023-11-07 13:50:10 +0800
commitf27c5ec67350af0dd18ba6f8b98f73d9513a1983 (patch)
tree674f8179af6fa1067a33afb6e62a7c176e3e0afa
parent81043b5990630b71375e250102eebe22a989fb4b (diff)
downloadkb-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.md160
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