gitpages

A collection of scripts to securely webhost and publish git repositories.
git clone https://scm.kuandu.systems/git-raw/gitpages.git
Log | Files | Refs | README | LICENSE

commit af3b692de1d09325e3cdb6d1fa841eca0d70010b
parent d89944bc4262750d2c40bf46a11639dbfea231c8
Author: Fred Großkopf <fred@kuandu.systems>
Date:   Fri, 18 Sep 2026 12:56:58 +0200

Updates README.md

Diffstat:
MREADME.md | 265+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 178 insertions(+), 87 deletions(-)

diff --git a/README.md b/README.md @@ -1,102 +1,193 @@ -# Gitpages +# gitpages -Gitpages is a small static site generator for bare Git repositories on OpenBSD. -It mirrors bare repositories into a web directory and generates HTML with -[stagit](https://codemadness.org/stagit). +`gitpages` generates static Git repository web pages using [stagit](https://git.codemadness.org/stagit/). -Updates run through a queue and a dedicated service user, keeping Git hooks fast -and the setup more secure. +It maintains a web-facing mirror of bare Git repositories and generates static HTML pages from them. Repository updates are triggered by Git `post-receive` hooks and processed asynchronously through a queue. -## Layout +`gitpages` itself is a POSIX shell application. The included `install.sh` is specific to OpenBSD. -```txt -push by git user - -> post-receive hook - -> queue file +## Requirements -gitpages-update.sh by _gitpages via cron - -> mirror GIT_SRC to GIT_RAW under WEB_ROOT - -> generate HTML in GIT_HTML under WEB_ROOT +- POSIX-compatible `/bin/sh` +- Git +- [stagit](https://git.codemadness.org/stagit/) +- `stagit-index` -httpd serves WEB_ROOT as www -``` +The installer also expects the OpenBSD utilities and account-management commands provided by the base system. -Example: +## Installation -```txt -/var/www/htdocs/scm.example.site/ -├── git/ -│ └── myrepo/ -└── git-raw/ - └── myrepo.git -``` +Run the installer as root: -## Components + ./install.sh <git-user> <git-src> <web-root> -- `install.sh` sets up users, directories, cron, and config. -- `uninstall.sh` removes the service setup. -- `gitpages-init-repos.sh` installs metadata and hooks for repositories. -- `post-receive.hook` queues repository updates. -- `gitpages-mirror-git.sh` mirrors bare repositories. -- `gitpages.sh` generates stagit HTML. -- `gitpages-update.sh` processes the queue. -- `gitpages-regenerate.sh` rebuilds everything. +For example: -## Quick start + ./install.sh git /srv/git /var/www/htdocs -```sh -doas pkg_add git stagit -doas ./install.sh git /home/git/public-repos /var/www/htdocs/scm.example.site -doas -u git ./gitpages-init-repos.sh -doas -u _gitpages ./gitpages-regenerate.sh -``` +Where: + +- `git-user` is the existing Unix account used to receive Git pushes. +- `git-src` is the directory containing the bare Git repositories. +- `web-root` is the directory from which the generated pages will be served. + +The installer creates the following system resources: + + /usr/local/sbin/gitpages + /usr/local/sbin/gitpages.post-receive.hook + /etc/gitpages.conf + /var/gitpages/ + /var/log/gitpages/ + /var/spool/gitpages/queue/ + +It also creates the `_gitpages` service account and `gitpages` group, configures `newsyslog`, and installs a cron job that processes the update queue every five minutes. + +If `/etc/gitpages.conf` already exists, the installer leaves it unchanged. + +## Repository setup + +After installation, prepare the repositories: + + gitpages setup /srv/git + +`setup` is interactive. For each bare repository it asks for: + +- description +- owner/contact +- URL + +It also installs the `post-receive` hook required to queue repository updates. + +If no source directory is specified, `gitpages setup` uses `GIT_SRC` from `/etc/gitpages.conf`: + + gitpages setup + +The account running `gitpages setup` must have write access to the source repositories because the command modifies their metadata and hooks. + +## How it works + +A push to a configured bare repository runs the `post-receive` hook. The hook places the repository in the update queue. + +The `_gitpages` cron job periodically runs: + + gitpages process_queue + +For each queued repository, `gitpages`: + +1. mirrors the repository into the web-facing `git-raw` directory; +2. runs `stagit` to generate the repository pages; +3. copies optional assets; +4. publishes the generated pages; +5. regenerates the repository index. + +The queue and generated files are kept outside the Git source tree. + +## Directory layout + +With the default installation: + + /var/gitpages/ + ├── assets/ + └── staging/ + + /var/spool/gitpages/ + └── queue/ + + /var/log/gitpages/ + +The web root contains: + + <web-root>/ + ├── git-raw/ + │ └── *.git + └── git/ + ├── index.html + └── <repository>/ + └── ... + +`git-raw` contains bare repository mirrors suitable for serving Git's smart/dumb HTTP data. `git` contains the generated stagit HTML. ## Configuration -`/etc/gitpages.conf`: - -- `GIT_SRC`: source directory containing bare repositories. -- `WEB_ROOT`: required document root for httpd. -- `GIT_RAW`: subdirectory for mirrored repos. -- `GIT_HTML`: subdirectory for generated HTML. -- `ASSETS_DIR`: optional static files for repo pages. -- `INDEX_TITLE`: optional title for `index.html`. -- `INDEX_DESCRIPTION`: optional description for `index.html`. -- `REPO_TITLE_DESCRIPTION`: optional repo title suffix. - -Defaults written by `install.sh`: - -- `GIT_RAW=git-raw` -- `GIT_HTML=git` -- `ASSETS_DIR=/var/gitpages/assets` - -## httpd - -```httpd -server "scm.example.site" { - listen on * port 80 - root "/htdocs/scm.example.site" - location "/git/*" { directory auto index } - location "/git-raw/*" { directory auto index } -} -``` - -## Notes - -- Edit `/etc/gitpages.conf` to set page metadata or change paths. -- When a new bare repository is added to `GIT_SRC`, run `gitpages-init-repos.sh` for it. -- By default, `gitpages-update.sh` runs from `_gitpages` cron every 5 minutes. -- Logs are written to `/var/log/gitpages/update.log`. -- Pending jobs are in `/var/spool/gitpages/queue`. - -## Security - -- The post-receive hook only writes entries to `/var/spool/gitpages/queue/`. -- The queue directory is restricted to the `gitpages` group. -- Failed jobs stay queued for retry. -- `_gitpages` is a service user with no login shell. -- `_gitpages` performs mirroring and HTML generation. -- `httpd` serves only the generated files under `WEB_ROOT`. -- `WEB_ROOT` is owned by `root:wheel`; only the generated subdirectories are writable by `_gitpages`. -- The `git` user must have read access to `GIT_SRC`. -- Source repositories and public web output are kept separate. +The default configuration file is: + + /etc/gitpages.conf + +A minimal configuration is: + + GIT_SRC=/srv/git + WEB_ROOT=/var/www/htdocs + GIT_RAW=git-raw + GIT_HTML=git + ASSETS_DIR=/var/gitpages/assets + +Optional settings can be added to customize generated pages: + + INDEX_TITLE=My Git Repositories + INDEX_DESCRIPTION=Source code and project repositories + REPO_TITLE_DESCRIPTION= - My Git repositories + +`gitpages generate` accepts an alternative configuration file: + + gitpages generate -c /path/to/gitpages.conf + +## Commands + +### `gitpages setup [SRC]` + +Prepare all bare repositories in `SRC` for use with `gitpages`. + +If `SRC` is omitted, `GIT_SRC` from `/etc/gitpages.conf` is used. + +### `gitpages generate [-c CONFIG] [REPO]` + +Generate static pages. + +Without `REPO`, all repositories configured in `GIT_SRC` are processed. + +With `REPO`, only the specified repository is generated. + +For a full generation, repositories are first mirrored from `GIT_SRC` into `GIT_RAW`. + +### `gitpages process_queue [-c CONFIG]` + +Process repositories waiting in the update queue. + +This command is normally run automatically by cron: + + */5 * * * * /usr/local/sbin/gitpages process_queue + +A lock prevents multiple queue processors from running simultaneously. + +## Web server + +The generated files can be served by any web server capable of serving static files and Git HTTP repository data. + +On OpenBSD, `httpd` can be used to serve the configured web root. + +If `httpd` is configured with a `chroot`, the `WEB_ROOT` path used by `gitpages` refers to the filesystem path on the host, while the corresponding path in the `httpd` configuration is relative to its chroot. + +## Uninstallation + +Run the uninstaller as root: + + ./uninstall.sh + +The uninstaller removes the files and system resources created by the installer, including: + +- installed `gitpages` scripts +- `_gitpages` service account +- `gitpages` group +- `/var/gitpages` +- `/var/log/gitpages` +- `/var/spool/gitpages/queue` +- the `newsyslog` entry + +It does **not** remove: + +- Git repositories +- the web root +- generated web content +- `/etc/gitpages.conf` + +The default assets directory under `/var/gitpages/assets` may contain administrator-supplied files. The uninstaller asks for confirmation before removing `/var/gitpages`.