From 214f4bab8b852e9b66d909bc22e5f9119da7dfb5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 29 Dec 2025 18:28:13 +0800 Subject: initial commit --- Caddyfile | 22 ++++++++++++++++++++++ Dockerfile | 20 ++++++++++++++++++++ README | 44 ++++++++++++++++++++++++++++++++++++++++++++ cgitrc.template | 27 +++++++++++++++++++++++++++ config.env | 16 ++++++++++++++++ entrypoint.sh | 19 +++++++++++++++++++ start_container.sh | 37 +++++++++++++++++++++++++++++++++++++ 7 files changed, 185 insertions(+) create mode 100644 Caddyfile create mode 100644 Dockerfile create mode 100644 README create mode 100644 cgitrc.template create mode 100644 config.env create mode 100644 entrypoint.sh create mode 100755 start_container.sh diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..b783e7b --- /dev/null +++ b/Caddyfile @@ -0,0 +1,22 @@ +{$DOMAIN} { + handle {$CGIT_CSS} { + root * /usr/share/webapps/cgit + file_server + } + + handle {$CGIT_LOGO} { + root * /usr/share/webapps/cgit + file_server + } + + handle { + reverse_proxy unix/{$FCGI_SOCK} { + transport fastcgi { + env SCRIPT_FILENAME /usr/share/webapps/cgit/cgit.cgi + env QUERY_STRING {query} + env HTTP_HOST {host} + env PATH_INFO {path} + } + } + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..35208e9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM alpine:latest + +RUN apk add --no-cache \ + caddy \ + cgit \ + git \ + fcgiwrap \ + spawn-fcgi \ + gettext \ + openssl + +COPY cgitrc.template /etc/cgitrc.template +COPY Caddyfile /etc/caddy/Caddyfile +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +# 80 required for Let's Encrypt HTTP-01 challenge, 443 for HTTPS +EXPOSE 80 443 + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/README b/README new file mode 100644 index 0000000..c37fae2 --- /dev/null +++ b/README @@ -0,0 +1,44 @@ +CGIT-CADDY CONTAINER + +Build: + podman build -t cgit-caddy . + +Run (first time or after changes): + ./start_container.sh + +Run (manual): + podman run -d \ + --name cgit \ + --network public-routed \ + --ip 10.89.0.2 \ + --cap-add=NET_ADMIN \ + --env-file config.env \ + -v cgit_data:/data \ + -v /git:/git \ + localhost/cgit-caddy + + sleep 2 + podman exec cgit ip addr add 37.27.166.242/32 dev eth0 + ip route add 37.27.166.242/32 via 10.89.0.2 + +Restart: + podman restart cgit + +Stop: + podman stop cgit && podman rm cgit && ip route del 37.27.166.242/32 + +Cleanup (remove everything): + podman stop cgit + podman rm cgit + podman volume rm cgit_data + ip route del 37.27.166.242/32 + podman network rm public-routed # only if no other containers use it + +Logs: + podman logs -f cgit + +Shell: + podman exec -it cgit sh + +Create repo: + git init --bare /git/myrepo diff --git a/cgitrc.template b/cgitrc.template new file mode 100644 index 0000000..950bf64 --- /dev/null +++ b/cgitrc.template @@ -0,0 +1,27 @@ +css=${CGIT_CSS} +logo=${CGIT_LOGO} +root-title=Git Repositories +root-desc= +scan-path=${GIT_PATH} + +# Features +enable-index-links=1 +enable-commit-graph=1 +enable-log-filecount=1 +enable-log-linecount=1 +enable-http-clone=1 +enable-blame=1 + +# Downloads +snapshots=tar.gz zip tar.xz + +# Clone URL +clone-url=https://$HTTP_HOST/$CGIT_REPO_URL + +# Caching (0 = disabled) +cache-size=0 + +# Appearance +max-repo-count=50 +max-stats=year +side-by-side-diffs=1 diff --git a/config.env b/config.env new file mode 100644 index 0000000..417ce14 --- /dev/null +++ b/config.env @@ -0,0 +1,16 @@ +# Container config +CONTAINER_NAME=cgit +DOMAIN=git2.noml.ch + +# Network +PRIVATE_SUBNET=10.89.0.0/24 +PRIVATE_IP=10.89.0.2 +PUBLIC_IP=37.27.166.242 +NETWORK=public-routed + +# Paths (inside container) +GIT_PATH=/git +XDG_DATA_HOME=/data # mounted as caddy_data volume, stores SSL certs +CGIT_CSS=/cgit.css +CGIT_LOGO=/cgit.png +FCGI_SOCK=/run/fcgiwrap.sock diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..bf3753f --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -e + +# Check cert matches domain, else clear and renew +if [ -d "/data/caddy/certificates" ]; then + CERT_CN=$(echo | openssl s_client -connect ${DOMAIN}:443 2>/dev/null | openssl x509 -noout -subject 2>/dev/null | grep -o "CN=.*" | cut -d= -f2 || true) + if [ -n "$CERT_CN" ] && [ "$CERT_CN" != "$DOMAIN" ]; then + echo "Cert mismatch: $CERT_CN != $DOMAIN, clearing certs" + rm -rf /data/caddy/certificates/ + fi +fi + +# Generate cgitrc from template +envsubst < /etc/cgitrc.template > /etc/cgitrc + +spawn-fcgi -s ${FCGI_SOCK} /usr/bin/fcgiwrap +chmod 666 ${FCGI_SOCK} + +exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile diff --git a/start_container.sh b/start_container.sh new file mode 100755 index 0000000..bf1c167 --- /dev/null +++ b/start_container.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -e + +# Load config +source "$(dirname "$0")/config.env" + +# Create network if not exists +if ! podman network exists ${NETWORK}; then + echo "Creating network: ${NETWORK} (subnet: ${PRIVATE_SUBNET})" + podman network create --subnet=${PRIVATE_SUBNET} ${NETWORK} +else + echo "Network exists: ${NETWORK}" +fi + +# Stop existing container if running +podman stop ${CONTAINER_NAME} 2>/dev/null || true +podman rm ${CONTAINER_NAME} 2>/dev/null || true +ip route del ${PUBLIC_IP}/32 2>/dev/null || true + +# Run container +podman run -d \ + --name ${CONTAINER_NAME} \ + --network ${NETWORK} \ + --ip ${PRIVATE_IP} \ + --cap-add=NET_ADMIN \ + --env-file "$(dirname "$0")/config.env" \ + -v ${CONTAINER_NAME}_data:/data \ + -v /git:/git \ + localhost/cgit-caddy + +# Setup public IP +sleep 2 +IFACE=$(podman exec ${CONTAINER_NAME} sh -c "ip -o link | grep -v lo | head -1 | cut -d: -f2 | tr -d ' ' | cut -d@ -f1") +podman exec ${CONTAINER_NAME} ip addr add ${PUBLIC_IP}/32 dev ${IFACE} +ip route add ${PUBLIC_IP}/32 via ${PRIVATE_IP} + +echo "Running at https://${DOMAIN}/" -- cgit v1.2.3