cmc/dotfiles

Using GNU Stow to manage my dotfiles.

clone: git clone https://gitbay.org/cmc/dotfiles.git

fd10a8a033e1e1c5d016968c2fbd296ec6ae1656

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-08-02T21:49:19Z

add git.conf
 linux/nginx/etc/nginx/conf.d/git.conf | 91 +++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/linux/nginx/etc/nginx/conf.d/git.conf b/linux/nginx/etc/nginx/conf.d/git.conf
new file mode 100644
index 0000000..884000c
--- /dev/null
+++ b/linux/nginx/etc/nginx/conf.d/git.conf
@@ -0,0 +1,91 @@
+# git.krz.sh -- cgit (fcgiwrap)
+# Cloudflare Tunnel ingress: git.krz.sh -> http://localhost:10046
+# Repos are scanned from /git (scan-path in /etc/cgitrc).
+
+server {
+	listen 10046;
+	server_name git.krz.sh;
+	error_log /var/log/nginx/git.krz.sh.error.log;
+
+	include custom.d/basic.conf;
+	include custom.d/security/strict-transport-security.conf;
+	include custom.d/security/permissions-policy.conf;
+
+	# The shared CSP (default-src 'self', no style-src) breaks cgit: the
+	# pygments source-filter writes an inline <style> block into every blob
+	# view, and the commit graph uses inline styles. Scope 'unsafe-inline'
+	# to styles only, on this vhost only.
+	add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; upgrade-insecure-requests" always;
+
+	root /usr/share/cgit;
+	port_in_redirect off;
+
+	# Serve cgit's static assets directly rather than through the CGI.
+	location /cgit-css/ {
+		alias /usr/share/cgit/;
+		expires 30d;
+	}
+
+	# Site branding (logo + favicon). Served from this origin on purpose:
+	# the CSP above allows img-src 'self' only, so pulling these from the
+	# img.* vhost would be blocked. Only the two white wordmarks are
+	# world-readable in that directory; the purple variants are not.
+	location /assets/ {
+		alias /var/www/img/krz/;
+		expires 30d;
+	}
+
+	# --- Smart HTTP: read-only clone/fetch --------------------------------
+	# Anonymous push is never allowed. Refuse receive-pack explicitly so it
+	# fails loudly instead of falling through to cgit and 404ing.
+	location ~ ^/.+\.git/git-receive-pack$ {
+		return 403;
+	}
+
+	# These paths belong to git, not cgit. None of them collide with cgit's
+	# own repo pages (cgit uses /refs/, /tree/, /plain/, ... not /info/refs
+	# or /objects/).
+	location ~ ^/.+\.git/(HEAD|info/refs|objects/.*|git-upload-pack)$ {
+		include fastcgi_params;
+
+		fastcgi_pass unix:/run/fcgiwrap.socket;
+		fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
+		fastcgi_param GIT_PROJECT_ROOT /git;
+		fastcgi_param GIT_HTTP_EXPORT_ALL 1;
+		fastcgi_param PATH_INFO $uri;
+		fastcgi_param QUERY_STRING $args;
+
+		# /git is owned by uid 1001, which maps to no account on this host,
+		# so git rejects every repo as "dubious ownership". Scope the
+		# exception to this backend via env instead of relaxing the check
+		# globally in /etc/gitconfig. Note: git 2.43 does not support path
+		# globs here, so "*" is the only working value.
+		fastcgi_param GIT_CONFIG_COUNT 1;
+		fastcgi_param GIT_CONFIG_KEY_0 safe.directory;
+		fastcgi_param GIT_CONFIG_VALUE_0 "*";
+
+		# Clones stream large packfiles -- don't spool them to disk first.
+		fastcgi_buffering off;
+		fastcgi_read_timeout 900;
+		client_max_body_size 64m;
+	}
+
+	location / {
+		try_files $uri @cgit;
+	}
+
+	location @cgit {
+		include fastcgi_params;
+
+		fastcgi_pass unix:/run/fcgiwrap.socket;
+		fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
+		fastcgi_param PATH_INFO $uri;
+		fastcgi_param QUERY_STRING $args;
+		fastcgi_param HTTP_HOST $host;
+
+		# Snapshot tarballs of large repos can take a while to stream.
+		fastcgi_read_timeout 300;
+		fastcgi_buffer_size 128k;
+		fastcgi_buffers 16 64k;
+	}
+}