diff options
| author | Arseney300 <Arseney300@gmail.com> | 2026-02-20 04:56:52 +0700 |
|---|---|---|
| committer | Arseney300 <Arseney300@gmail.com> | 2026-02-20 04:56:52 +0700 |
| commit | b68790d86a40294ba035b93e40b29f1a071359a1 (patch) | |
| tree | 8eccd2412be8c287bf5de1d835955b44e8515cab | |
| parent | ee7d961c638c3baa0ba12b0451fe5104fecc95a9 (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.md | 5 | ||||
| -rw-r--r-- | git-server/cgit/Dockerfile | 18 | ||||
| -rw-r--r-- | git-server/cgit/cgitrc | 30 | ||||
| -rw-r--r-- | git-server/cgit/entrypoint.sh | 7 | ||||
| -rw-r--r-- | git-server/cgit/nginx.conf | 32 | ||||
| -rw-r--r-- | git-server/server.yaml | 9 | ||||
| -rw-r--r-- | nginx/nginx.conf | 51 | ||||
| -rw-r--r-- | nginx/run_certbot.sh | 3 |
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 |
