README.md
socle๐
A read-only web host for local git repositories.
Point it at some repos via a small config file, and it serves them:
browse trees and files at any ref, with markdown rendered to HTML,
and git clone works anonymously over smart HTTP.
No javascript required, no push, no auth, no database, no dynamic anything beyond rendering.
socle shows committed state at refs, never the working tree. (That's the line between socle and its sibling vitrine: vitrine shows the filesystem as it is right now; socle shows what git has committed.)
Config๐
socle takes exactly one config file, via the required -config flag
(there is no default location and no search).
The format is YAML:
repos:
parnass:
path: "%"
work/infra/deploy:
path: ../deploy
description: "deploy scripts"
reposmaps URL names to local git repositories. A name may contain slashes, so the URL space can have depth. Name segments are limited to[A-Za-z0-9._-], with no leading dot or dash, and no name may be a path-prefix of another (that keeps URL dispatch unambiguous).path(required) is the repository to serve: a worktree checkout or a bare repo, both work. The placeholder"%"means "same as the repo name". Relative paths resolve against the config file's directory, which makes a config portable alongside the repos it describes.description(optional) shows on the index and the repo's home page.
A bad config (parse error, unknown key, invalid name, nothing configured at all) is a startup error: socle refuses to run rather than serve the wrong thing. A configured directory that's absent or not a git repository is only a warning and a skip, so one config can describe repos that only some hosts happen to have.
Browsing๐
Every repo gets the same small set of pages:
/ index of all repos
/<name>/ repo home: rendered README, clone URL, branches, tags
/<name>/tree/<ref>/<path> directory listings and file views
/<name>/raw/<ref>/<path> the file's raw bytes
/<name>/log/<ref> commit log, newest first
/<name>/commit/<ref> one commit: metadata, message, and its diff
<ref> is a branch, tag, HEAD, or any commit sha.
File views render markdown, show text in a code block, and inline images;
anything binary or oversized degrades to a link to the raw bytes.
URLs that address a commit by its full sha are served with immutable cache headers:
they can never mean anything else.
Cloning๐
The repo's home URL is its clone URL:
git clone http://host/name
Fetch is anonymous, over git's smart HTTP transport (protocol v2 included);
a trailing .git on the URL also works, since git clients and habits both produce it.
There is no push: socle never runs anything but read-only git subcommands,
and a push attempt is refused explicitly.
Rendering and theming๐
Pages are rendered by vitrine's display package (a sibling project, wired in via a replace directive in go.mod), so socle inherits
its look and its markdown dialect: GFM with callout boxes and server-rendered
dot diagrams, heading anchors, and light/dark following the browser's
prefers-color-scheme.
Each host wears an accent color derived from its hostname
(the -theme-seed flag substitutes any string),
so several socle instances in several tabs stay recognizable at a glance.
Known limits๐
- Branch and tag names containing
/aren't addressable in URLs (they still work by sha), and the accepted ref charset is narrower than git's own rules. - The log page shows the newest 100 commits; there is no pagination past that.
- The clone URL on a repo's home page reflects the scheme and host of the direct request; behind a rewriting or TLS-terminating proxy it would be wrong.
Deployment๐
Run socle as your own user, under a systemd user unit. No root anywhere.
-
Build and install the binary somewhere on your user's path:
go build -o ~/bin/socle . -
Write your config, e.g.
~/fusion/.socle.cfg, with paths relative to that directory (see Config above). -
Install the unit file from this repo as a user unit:
mkdir -p ~/.config/systemd/user cp socle.service ~/.config/systemd/user/ systemctl --user daemon-reload systemctl --user enable --now socleAdjust
ExecStartin the unit if your binary, config, or port should differ. -
Keep it running after logout (user units otherwise stop with your session):
loginctl enable-linger $USER
Check on it with systemctl --user status socle
and journalctl --user -u socle -f.
README.md ยท 4.6 KiB ยท d3c2758b67