Write README for self-hosters #3

Closed
opened 2026-08-23 15:28:13 +02:00 by myrmidex · 1 comment
Owner

Context

web/ has no README.md. Blocked by #2 — the install section has to point at a published
image, and until that pipeline exists there is nothing to document.

Research

Findings from 31 real self-hosted project READMEs (Miniflux, Vaultwarden, Uptime Kuma,
Docmost, Gotify, linkding, Kutt, Umami, Memos, Forgejo, Gitea and others), fetched as raw
markdown:

  • Do not inline the compose file. Only 1 of 31 does (Vaultwarden, 11 lines, single
    service). Link the repo's compose.yaml, or use the curl-then-up pattern.
  • Target 70–110 lines. Median across the corpus is ~125; the best small ones are
    Forgejo 46, Docmost 62, Vikunja 66, Gotify 68. For contrast, ffr's is 203.
  • Features before install is near-universal.
  • One hero screenshot near the top, after tagline/badges, before Features. A separate
    ## Screenshots section is for 3+ images; we have one
    (docs/screenshots/anagram-finder.png).
  • Config: name the 1–3 genuinely required env vars inline, link .env.example. Full
    tables rot — Kutt's 48-row table has a live typo (OIDC_POMPT) as the cautionary example.
  • Licence: one sentence, near the bottom. e.g. "Anagram Finder is free software,
    licensed under the GNU AGPL-3.0." Nobody reproduces licence text.
  • Badges are thinning — 9 of 31 have none, including Miniflux, linkding, Plausible,
    Forgejo. Sane set here: licence, release, build.

Anti-patterns to avoid: table of contents on a short README, emoji headings (they break
anchor links), duplicating install steps that also live elsewhere.

Proposed structure

# Anagram Finder
badges (licence, release, build)
one-paragraph tagline
![screenshot](docs/screenshots/anagram-finder.png)
## Features
## Self-hosting          <- quick start, links compose.yaml from #2
## Configuration         <- APP_KEY, APP_URL, DB_* inline; link .env.example
## Development           <- clone -> nix-shell, dev-* command table, service URL table
## Contributing
## License

The Development section can follow ffr's, which documents nix-shell plus a table of the
dev-* helpers — those already exist in our shell.nix.

Acceptance

  • README.md at repo root, roughly 70–110 lines
  • Screenshot renders (relative path, verified on Forgejo)
  • Quick start works verbatim against the image published by #2
  • Only genuinely required env vars listed; rest deferred to .env.example
  • Licence section, one sentence, links LICENSE
  • No compose YAML inlined

Open question

Whether to add CONTRIBUTING.md — present in ~24 of 31 projects surveyed, and ffr has one.
Out of scope unless we want it; the README can link it later.

## Context `web/` has no `README.md`. Blocked by #2 — the install section has to point at a published image, and until that pipeline exists there is nothing to document. ## Research Findings from 31 real self-hosted project READMEs (Miniflux, Vaultwarden, Uptime Kuma, Docmost, Gotify, linkding, Kutt, Umami, Memos, Forgejo, Gitea and others), fetched as raw markdown: - **Do not inline the compose file.** Only 1 of 31 does (Vaultwarden, 11 lines, single service). Link the repo's `compose.yaml`, or use the curl-then-up pattern. - **Target 70–110 lines.** Median across the corpus is ~125; the best small ones are Forgejo 46, Docmost 62, Vikunja 66, Gotify 68. For contrast, ffr's is 203. - **Features before install** is near-universal. - **One hero screenshot near the top**, after tagline/badges, before Features. A separate `## Screenshots` section is for 3+ images; we have one (`docs/screenshots/anagram-finder.png`). - **Config: name the 1–3 genuinely required env vars inline, link `.env.example`.** Full tables rot — Kutt's 48-row table has a live typo (`OIDC_POMPT`) as the cautionary example. - **Licence: one sentence, near the bottom.** e.g. "Anagram Finder is free software, licensed under the GNU AGPL-3.0." Nobody reproduces licence text. - **Badges are thinning** — 9 of 31 have none, including Miniflux, linkding, Plausible, Forgejo. Sane set here: licence, release, build. Anti-patterns to avoid: table of contents on a short README, emoji headings (they break anchor links), duplicating install steps that also live elsewhere. ## Proposed structure ``` # Anagram Finder badges (licence, release, build) one-paragraph tagline ![screenshot](docs/screenshots/anagram-finder.png) ## Features ## Self-hosting <- quick start, links compose.yaml from #2 ## Configuration <- APP_KEY, APP_URL, DB_* inline; link .env.example ## Development <- clone -> nix-shell, dev-* command table, service URL table ## Contributing ## License ``` The Development section can follow ffr's, which documents `nix-shell` plus a table of the `dev-*` helpers — those already exist in our `shell.nix`. ## Acceptance - [ ] `README.md` at repo root, roughly 70–110 lines - [ ] Screenshot renders (relative path, verified on Forgejo) - [ ] Quick start works verbatim against the image published by #2 - [ ] Only genuinely required env vars listed; rest deferred to `.env.example` - [ ] Licence section, one sentence, links `LICENSE` - [ ] No compose YAML inlined ## Open question Whether to add `CONTRIBUTING.md` — present in ~24 of 31 projects surveyed, and ffr has one. Out of scope unless we want it; the README can link it later.
myrmidex added this to the v0.1.0 milestone 2026-08-23 15:28:13 +02:00
myrmidex added the
docs
label 2026-08-23 15:28:13 +02:00
myrmidex self-assigned this 2026-08-23 15:28:13 +02:00
myrmidex added a new dependency 2026-08-23 15:28:18 +02:00
Author
Owner

Done — 6fee71e

103 lines, following the structure from the research in this ticket.

Acceptance

  • README.md at repo root, roughly 70–110 lines — 103
  • Screenshot renders — relative path to docs/screenshots/anagram-finder.png, verified present
  • Quick start works against the published image — both raw URLs it curls return 200
  • Only genuinely required env vars listed — four in the table, rest deferred to .env.example
  • Licence section, one sentence, links LICENSE
  • No compose YAML inlinedgrep -c '^services:' returns 0

Every link checked: four local paths resolve, six remote URLs return 200 — including the two
curl lines in the quick start, which are the most likely thing to break silently.

Anti-patterns from the research all avoided: no table of contents, no emoji headings, no
duplicated install steps.

Changed from the plan

The quick start originally downloaded .env.example, but that file has 49 non-comment lines of
Laravel internals while compose reads only six variables. It now generates a four-line .env
with openssl directly, so a self-hoster gets a working stack without reading framework config.

Deployment gaps found while writing it

Both fixed in a separate commit, since they are behaviour changes rather than docs:

  • The published port was hardcoded to 8000, so anyone deploying had to edit compose.yaml.
    Now ${APP_PORT:-8000}.
  • Laravel did not trust forwarded headers. Behind a TLS-terminating proxy it would have seen
    plain HTTP and generated http:// redirects onto an https:// page — browsers block those as
    mixed content. find() redirects on every search, so this would have been immediately
    visible. Added trustProxies(at: '*').

Open question from the ticket

CONTRIBUTING.md — present in ~24 of the 31 projects surveyed, and ffr has one. Not added; the
README links Issues directly. Worth its own ticket if wanted.

## Done — `6fee71e` 103 lines, following the structure from the research in this ticket. ### Acceptance - **README.md at repo root, roughly 70–110 lines** — 103 - **Screenshot renders** — relative path to `docs/screenshots/anagram-finder.png`, verified present - **Quick start works against the published image** — both raw URLs it curls return 200 - **Only genuinely required env vars listed** — four in the table, rest deferred to `.env.example` - **Licence section, one sentence, links LICENSE** - **No compose YAML inlined** — `grep -c '^services:'` returns 0 Every link checked: four local paths resolve, six remote URLs return 200 — including the two `curl` lines in the quick start, which are the most likely thing to break silently. Anti-patterns from the research all avoided: no table of contents, no emoji headings, no duplicated install steps. ### Changed from the plan The quick start originally downloaded `.env.example`, but that file has 49 non-comment lines of Laravel internals while compose reads only six variables. It now generates a four-line `.env` with `openssl` directly, so a self-hoster gets a working stack without reading framework config. ### Deployment gaps found while writing it Both fixed in a separate commit, since they are behaviour changes rather than docs: - **The published port was hardcoded** to 8000, so anyone deploying had to edit `compose.yaml`. Now `${APP_PORT:-8000}`. - **Laravel did not trust forwarded headers.** Behind a TLS-terminating proxy it would have seen plain HTTP and generated `http://` redirects onto an `https://` page — browsers block those as mixed content. `find()` redirects on every search, so this would have been immediately visible. Added `trustProxies(at: '*')`. ### Open question from the ticket `CONTRIBUTING.md` — present in ~24 of the 31 projects surveyed, and ffr has one. Not added; the README links Issues directly. Worth its own ticket if wanted.
Sign in to join this conversation.
No labels
bug
ci
docs
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference: anagram-finder/web#3
No description provided.