Using Caddy Containers and Cgit to Display Git Repositories

Prerequisites

Easily Build Your Private Git Server with Caddy and Containers (Git Over HTTPS)

Introduction

After following the previous tutorial, we now have an accessible Git server. Now we want to display the repository list from this Git server through a web page.

Final Result

Implementation Steps

1. Update Container Image

First, we need to add cgit and related dependencies to our custom Caddy image.

Re-edit custom-containerfile/Containerfile:

FROM docker.io/library/caddy:2-builder AS builder

RUN xcaddy build \
    --with github.com/aksdb/caddy-cgi/v2

FROM docker.io/library/caddy:latest

RUN apk update && apk add --no-cache git git-daemon cgit python3 py3-pygments py3-markdown py3-docutils groff

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

2. Configure Caddyfile

Next, modify the Caddyfile to handle Git’s HTTP protocol and configure cgit’s CGI service.

git.your-domain.com {
 @git {
  header User-Agent git/*
 }

 route {
  # Enable basic authentication to protect the entire service
  basic_auth {
   # Use `caddy hash-password` command to generate your password hash
   # Replace "your_username" with your username
   # Replace "$2a$14$..." with the generated hash password
   your_username $2a$14$ABC...
  }

  handle /cgit.* {
   root * /usr/share/webapps/cgit
   file_server
  }

  handle /favicon.ico {
   root * /usr/share/webapps/cgit
   file_server
  }

  handle @git {
   cgi * /usr/libexec/git-core/git-http-backend {
    env GIT_PROJECT_ROOT=/git-repos GIT_HTTP_EXPORT_ALL=1
   }
  }

  handle {
   cgi * /usr/share/webapps/cgit/cgit.cgi {
    env CGIT_CONFIG=/cgitrc
   }
  }
 }
}

3. Configure cgit

Create a cgitrc file to configure cgit’s appearance and behavior. This file defines the repository root directory, page title, logo, CSS styles, etc.

# https://man.archlinux.org/man/cgitrc.5

root-title=Your Git Repositories

root-desc=A collection of personal and experimental projects

css=/cgit.css

logo=/cgit.png

favicon=/favicon.ico

enable-index-owner=1

enable-http-clone=1

enable-index-links=1

enable-blame=1

enable-commit-graph=1

enable-log-filecount=1

enable-log-linecount=1

branch-sort=age

max-stats=quarter

snapshots=tar.gz zip

readme=:README.md

source-filter=/usr/lib/cgit/filters/syntax-highlighting.py
about-filter=/usr/lib/cgit/filters/about-formatting.sh

# scan-path must be at the end of the file, otherwise the parameters set above will be invalid
scan-path=/git-repos

4. Check Directory Structure

After completing the above configuration, your project directory structure should look like this:

/my-caddy-git-server
├── Caddyfile
├── compose.yml
├── cgitrc
├── custom-containerfile/
│   └── Containerfile
├── git-repos/
│   └── (Git repositories will be stored here)
└── caddy_data/
    └── (Caddy's certificates and state will be stored here)

5. Update Compose File

To allow cgit to read the configuration, we need to modify the compose.yml file to mount the cgitrc file into the container.

name: git-server
services:
  git-server:
    # Specify to use our custom Containerfile for building
    build: ./custom-containerfile
    restart: unless-stopped
    ports:
      # Map HTTPS and HTTP ports
      - "443:443"
      - "80:80"
    volumes:
      # Mount Caddyfile
      - ./Caddyfile:/etc/caddy/Caddyfile
      # Mount directory for storing Git repositories
      - ./git-repos:/git-repos
      # Mount Caddy data volume for persisting TLS certificates
      - ./caddy_data:/data
      # Mount cgitrc
      - ./cgitrc:/cgitrc

6. Start and Access

Once everything is ready, start the service:

podman-compose up -d

After successful startup, visit https://git.your-domain.com to see the git repository list page generated by cgit.

0%