summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseney300 <Arseney300@gmail.com>2026-02-20 04:56:52 +0700
committerArseney300 <Arseney300@gmail.com>2026-02-20 04:56:52 +0700
commitb68790d86a40294ba035b93e40b29f1a071359a1 (patch)
tree8eccd2412be8c287bf5de1d835955b44e8515cab
parentee7d961c638c3baa0ba12b0451fe5104fecc95a9 (diff)
Add cgit web interface to git-server stack
Adds a lightweight cgit container (Alpine + fcgiwrap + nginx) that auto-discovers bare repos via scan-path and serves them read-only. Accessible at both cgit.swave.lol and swave.lol/cgit through the main nginx reverse proxy. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
-rw-r--r--doc/setup-guide.md5
-rw-r--r--git-server/cgit/Dockerfile18
-rw-r--r--git-server/cgit/cgitrc30
-rw-r--r--git-server/cgit/entrypoint.sh7
-rw-r--r--git-server/cgit/nginx.conf32
-rw-r--r--git-server/server.yaml9
-rw-r--r--nginx/nginx.conf51
-rw-r--r--nginx/run_certbot.sh3
8 files changed, 153 insertions, 2 deletions
diff --git a/doc/setup-guide.md b/doc/setup-guide.md
index 612ca20..26f09b7 100644
--- a/doc/setup-guide.md
+++ b/doc/setup-guide.md
@@ -10,6 +10,7 @@ Full instruction to build the server from a fresh Debian installation.
- `swave.lol`
- `blog.swave.lol`
- `jenkins.swave.lol`
+ - `cgit.swave.lol`
## 1. Install Docker
@@ -253,6 +254,7 @@ This requests certificates for:
- `swave.lol`
- `blog.swave.lol`
- `jenkins.swave.lol`
+- `cgit.swave.lol`
IMPORTANT: All DNS records must be pointing to the server before running certbot.
@@ -277,6 +279,8 @@ All services should now be accessible:
| `https://blog.swave.lol` | Ghost (blog, alias) |
| `https://swave.lol/jenkins` | Jenkins (path-based) |
| `https://jenkins.swave.lol` | Jenkins (subdomain) |
+| `https://swave.lol/cgit` | Cgit (path-based) |
+| `https://cgit.swave.lol` | Cgit (subdomain) |
| `http://<server-ip>:9000` | Portainer |
| `ssh://git@<server-ip>/repos/<repo>.git` | Git (SSH) |
| `git://<server-ip>/<repo>.git` | Git (daemon, read-only) |
@@ -287,6 +291,7 @@ All services should now be accessible:
```
git-network (172.22.0.0/16)
├── git-server (172.22.0.2)
+├── cgit
└── nginx (172.22.0.254)
ghost_network
diff --git a/git-server/cgit/Dockerfile b/git-server/cgit/Dockerfile
new file mode 100644
index 0000000..9da8b23
--- /dev/null
+++ b/git-server/cgit/Dockerfile
@@ -0,0 +1,18 @@
+FROM alpine:latest
+
+RUN apk add --no-cache \
+ cgit \
+ git \
+ nginx \
+ fcgiwrap \
+ spawn-fcgi \
+ py3-pygments
+
+COPY cgitrc /etc/cgitrc
+COPY nginx.conf /etc/nginx/nginx.conf
+COPY entrypoint.sh /entrypoint.sh
+RUN chmod +x /entrypoint.sh
+
+EXPOSE 80
+
+ENTRYPOINT ["/entrypoint.sh"]
diff --git a/git-server/cgit/cgitrc b/git-server/cgit/cgitrc
new file mode 100644
index 0000000..bf6ab31
--- /dev/null
+++ b/git-server/cgit/cgitrc
@@ -0,0 +1,30 @@
+# cgit config
+
+# Branding
+root-title=swave.lol git
+root-desc=Git repositories hosted on swave.lol
+
+# Repo discovery
+scan-path=/repos
+
+# Features
+enable-index-links=1
+enable-index-owner=0
+enable-log-filecount=1
+enable-log-linecount=1
+enable-commit-graph=1
+snapshots=tar.gz zip
+
+# Syntax highlighting via pygments
+source-filter=/usr/lib/cgit/filters/syntax-highlighting.py
+
+# About tab (use repo description file)
+readme=:README.md
+readme=:README
+
+# Cache
+cache-size=1000
+
+# URL style
+remove-suffix=1
+clone-prefix=git://swave.lol ssh://git@swave.lol/repos
diff --git a/git-server/cgit/entrypoint.sh b/git-server/cgit/entrypoint.sh
new file mode 100644
index 0000000..652ba73
--- /dev/null
+++ b/git-server/cgit/entrypoint.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Start fcgiwrap via spawn-fcgi on a unix socket
+spawn-fcgi -s /var/run/fcgiwrap.socket -U nginx -G nginx -- /usr/bin/fcgiwrap
+
+# Start nginx in foreground
+exec nginx
diff --git a/git-server/cgit/nginx.conf b/git-server/cgit/nginx.conf
new file mode 100644
index 0000000..64e35cb
--- /dev/null
+++ b/git-server/cgit/nginx.conf
@@ -0,0 +1,32 @@
+daemon off;
+worker_processes 1;
+error_log /var/log/nginx/error.log warn;
+
+events {
+ worker_connections 128;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+ sendfile on;
+
+ server {
+ listen 80;
+ server_name _;
+
+ # Serve cgit static assets directly
+ location /cgit-css/ {
+ alias /usr/share/webapps/cgit/;
+ }
+
+ location / {
+ fastcgi_pass unix:/var/run/fcgiwrap.socket;
+ fastcgi_param SCRIPT_FILENAME /usr/share/webapps/cgit/cgit.cgi;
+ fastcgi_param PATH_INFO $uri;
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_param HTTP_HOST $server_name;
+ include /etc/nginx/fastcgi_params;
+ }
+ }
+}
diff --git a/git-server/server.yaml b/git-server/server.yaml
index 2e32183..ff20a13 100644
--- a/git-server/server.yaml
+++ b/git-server/server.yaml
@@ -16,6 +16,15 @@ services:
git-network:
ipv4_address: 172.22.0.2
+ cgit:
+ build: ./cgit
+ restart: always
+ container_name: cgit
+ volumes:
+ - /var/git/repos:/repos:ro
+ networks:
+ - git-network
+
networks:
git-network:
diff --git a/nginx/nginx.conf b/nginx/nginx.conf
index b62b458..dd852d2 100644
--- a/nginx/nginx.conf
+++ b/nginx/nginx.conf
@@ -4,7 +4,7 @@ server {
listen 80;
listen [::]:80;
- server_name swave.lol blog.swave.lol jenkins.swave.lol;
+ server_name swave.lol blog.swave.lol jenkins.swave.lol cgit.swave.lol;
location / {
rewrite ^ https://$host$request_uri? permanent;
@@ -48,6 +48,15 @@ server {
charset utf-8;
+ # Cgit via path prefix on main domain
+ location /cgit {
+ proxy_pass http://cgit:80/;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
# Jenkins via path prefix on main domain
location /jenkins {
proxy_pass http://jenkins:8080/jenkins;
@@ -106,3 +115,43 @@ server {
proxy_set_header X-Forwarded-Proto $scheme;
}
}
+
+# Cgit — cgit.swave.lol
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+
+ server_name cgit.swave.lol;
+
+ server_tokens off;
+
+ ssl_certificate /var/letsencrypt/etc/letsencrypt/live/swave.lol/fullchain.pem;
+ ssl_certificate_key /var/letsencrypt/etc/letsencrypt/live/swave.lol/privkey.pem;
+
+ ssl_buffer_size 8k;
+
+ ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
+
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_prefer_server_ciphers on;
+
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+
+ ssl_ecdh_curve secp384r1;
+ ssl_session_tickets off;
+
+ # OCSP stapling
+ ssl_stapling on;
+ ssl_stapling_verify on;
+ resolver 8.8.8.8;
+
+ charset utf-8;
+
+ location / {
+ proxy_pass http://cgit:80;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+}
diff --git a/nginx/run_certbot.sh b/nginx/run_certbot.sh
index 3859d19..d265cce 100644
--- a/nginx/run_certbot.sh
+++ b/nginx/run_certbot.sh
@@ -20,4 +20,5 @@ docker run -it --rm \
--webroot-path=/data/letsencrypt \
-d $domain \
-d blog.$domain \
- -d jenkins.$domain
+ -d jenkins.$domain \
+ -d cgit.$domain