add README; switch unit file to systemd user-unit shape
commit 1a5958b537141fb7ca6a5e10a7c720adba550d61 · parent 8af31ec12b
· browse this tree
Ximianth, 2026-07-28 14:07:54 UTC
Deployment story is now: user unit in ~/.config/systemd/user plus loginctl enable-linger, binary in ~/bin, config per-realm (e.g. ~/fusion/.vitrine.cfg). No root anywhere in the happy path. The README documents the config format and the expose-git caveats (vitrine writes into .git; dumb-HTTP clones can be silently stale).
diff --git a/README.md b/README.md new file mode 100644 index 0000000..4690008 --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +vitrine +======= + +A tiny read-only webserver for putting local source trees on display. + +Point it at some directories via a small config file, and it serves them: +markdown renders to HTML, directories become listings, +and `?fmt=raw` on any URL serves the file bytes directly. +No javascript required, no uploads, no auth, no dynamic anything beyond rendering. + +Config +------ + +vitrine takes exactly one config file, via the required `-config` flag +(there is no default location and no search). +The format is YAML: + +```yaml +exhibits: + moonshot-1: + path: moonshot-1 + meta/research/some-topic: + path: ../elsewhere/some-topic + some-repo: + path: ../src/some-repo + expose-git: true +``` + +- `exhibits` maps URL prefixes to directories. + A prefix may contain slashes; the intermediate URL levels then serve synthetic listings + that reveal only the mounted subtrees. +- `path` (required) is the directory to serve. + Relative paths resolve against the config file's directory, + which makes a config portable alongside the trees it describes. + Absolute paths also work. +- `expose-git` (optional, default false): see below. + +A bad config (parse error, unknown key, missing path, or zero exhibits) +is a startup error: vitrine refuses to run rather than serve the wrong thing. + +expose-git +---------- + +By default, `.git` directories are invisible: hidden from listings and unreachable by direct URL. + +Setting `expose-git: true` on an exhibit flips that: +`.git` lists and serves like any other directory, +which makes `git clone http://host/exhibit/.git` work over git's dumb HTTP transport. + +Two caveats, read them before enabling: + +- **vitrine writes into that exhibit's `.git`.** + Dumb-HTTP clone requires `.git/info/refs` and `.git/objects/info/packs`, + and ordinary commits never maintain them, + so vitrine runs `git update-server-info` on the exhibit at startup. + This is a deliberate exception to vitrine's otherwise strictly read-only stance. +- **Dumb HTTP has dumb semantics.** + Clones reflect the refs as of the last `update-server-info` run, + so commits made after vitrine started are invisible to clones until it next runs + (currently: restart vitrine). + A stale clone succeeds silently at the old tip; there is no warning. + Concurrent `git gc` in the exhibit can also break an in-flight clone (loudly; retry works). + +Deployment +---------- + +Run vitrine as your own user, under a systemd user unit. No root anywhere. + +1. Build and install the binary somewhere on your user's path: + + ``` + go build -o ~/bin/vitrine . + ``` + +2. Write your config, e.g. `~/fusion/.vitrine.cfg`, + with paths relative to that directory (see Config above). + +3. Install the unit file from this repo as a *user* unit: + + ``` + mkdir -p ~/.config/systemd/user + cp vitrine.service ~/.config/systemd/user/ + systemctl --user daemon-reload + systemctl --user enable --now vitrine + ``` + + Adjust `ExecStart` in the unit if your binary or config live elsewhere. + +4. Keep it running after logout (user units otherwise stop with your session): + + ``` + loginctl enable-linger $USER + ``` + +Check on it with `systemctl --user status vitrine` +and `journalctl --user -u vitrine -f`. diff --git a/vitrine.service b/vitrine.service index 6325d0b..d7bcb28 100644 --- a/vitrine.service +++ b/vitrine.service @@ -1,11 +1,10 @@ [Unit] -Description=vitrine: tiny read-only web viewer for fusion source trees +Description=vitrine: tiny read-only web viewer for local source trees After=network.target [Service] -ExecStart=/usr/local/bin/vitrine -addr :8000 -User=exedev +ExecStart=%h/bin/vitrine -addr :8000 -config %h/fusion/.vitrine.cfg Restart=on-failure [Install] -WantedBy=multi-user.target +WantedBy=default.target