Files
stack/infra/gitea/README.md
kert 16f3b43974
Some checks failed
CI / skinny-install (aco) (push) Successful in 1m12s
CI / skinny-install (api) (push) Successful in 30s
CI / skinny-install (bcda) (push) Successful in 36s
CI / skinny-install (bib) (push) Successful in 35s
CI / skinny-install (bls) (push) Successful in 27s
CI / skinny-install (ccw) (push) Successful in 32s
CI / skinny-install (cli) (push) Successful in 41s
CI / skinny-install (cms) (push) Successful in 37s
CI / skinny-install (conf) (push) Successful in 38s
CI / skinny-install (opps) (push) Successful in 33s
CI / skinny-install (perf) (push) Successful in 38s
CI / skinny-install (pfs) (push) Successful in 38s
CI / skinny-install (rex) (push) Successful in 34s
Deploy / build-scan-report (push) Failing after 46s
Infra CI / notebooks (push) Failing after 25s
Infra CI / zotero (push) Successful in 12s
Infra CI / docs (push) Failing after 16s
CI / lint-test (push) Failing after 11m2s
Infra CI / mc (push) Successful in 21s
Infra CI / api (push) Successful in 29s
Package Supply Chain / pkg-supply-chain (push) Failing after 41s
feat: full session — mail servers, comment pipeline, PRISMA fetch, email ingest
Mail: Maddy on DO (corwins.media+Resend, fhirworx.io+Postmark),
touchless/stateless/idempotent. Gitea SMTP via env_file. CMS inbox
at cmsupdates@mail.fhirworx.io with IMAP→bib poller.

Bib: regulations.gov v4 client, Federal Register discovery, 164K
comment backfill (running), IMAP email ingest, Zotero sync routing.

PRISMA: altcha PoW solver, CrossRef DOI resolution, 83/129 PDFs.
Zotero: schema parity, ops module, CLI, fail-fast guard.
CI: docs.Dockerfile COPY glob fix (tracks #341).
Infra: Gitea+marimo fhirworx themes, IOM/OIG modules.
2026-04-16 09:04:38 -04:00

133 lines
5.3 KiB
Markdown

# Fhirworx Gitea image
This directory builds `fhirworx/gitea:<tag>` — upstream `go-gitea/gitea` at a
pinned tag with the fhirworx theme baked in via `bindata`. **No source
changes to upstream**; we only inject one CSS file and two brand SVGs into
the upstream tree before its own build runs.
## Layout
```
infra/gitea/
├── Dockerfile # multi-stage build, see below
├── .dockerignore
├── theme/
│ └── theme-fhirworx.css # ONE css file = the entire theme
├── brand/
│ ├── logo.svg # → assets/logo.svg → make generate-images
│ └── favicon.svg # → assets/favicon.svg
├── custom/ # bind-mounted at runtime as /var/lib/gitea/custom
│ └── templates/
│ └── home.tmpl # custom anonymous landing page
└── README.md # this file
```
## Staying downstream from upstream Gitea
Goal: track upstream cleanly, never fork the source.
The build does only three things to the upstream tree:
1. `COPY theme/theme-fhirworx.css web_src/css/themes/theme-fhirworx.css`
2. `COPY brand/logo.svg assets/logo.svg`
3. `COPY brand/favicon.svg assets/favicon.svg`
After these, the upstream `make clean-all build` runs unmodified — webpack
processes our theme into `public/assets/css/theme-fhirworx.css`, the image
generator regenerates every PNG/SVG variant from our SVGs, and `bindata`
embeds the whole `public/` tree into the Go binary.
### Bumping Gitea
```
# 1. Update the pinned tag
sed -i 's/GITEA_VERSION=v1\.[0-9.]\+/GITEA_VERSION=v1.NEW.VER/' Dockerfile
# 2. Diff our theme against upstream's reference
diff theme/theme-fhirworx.css \
<(curl -sL https://raw.githubusercontent.com/go-gitea/gitea/v1.NEW.VER/web_src/css/themes/theme-gitea-light.css)
# 3. Add any new --color-* vars upstream introduced
# 4. Rebuild
docker compose build gitea && docker compose up -d gitea
```
The theme file's variable order **mirrors upstream's `theme-gitea-light.css`
1:1**, on purpose, so step 2 produces a clean readable diff. Add variables
upstream added; refresh values you've remapped.
## Theme contract
The theme is a complete drop-in replacement for upstream's
`theme-gitea-light.css`. It defines:
- **All ~140 `--color-*` variables** Gitea references. Any var left undefined
resolves to CSS `initial` (transparent bg / black text), which breaks
surfaces like the navbar, secondary-nav, footer, clone panel, menu hover
states. Historical bug: an early version defined ~30 vars and many
components broke.
- **`--fonts-override`** — Gitea's `base.css` composes
`--fonts-regular: var(--fonts-override, var(--fonts-proportional)), ...`.
Setting `--fonts-override` propagates the editorial type (Source Serif 4)
through every Fomantic UI component (menus, buttons, tabs, inputs).
- **A defensive `#navbar` color sweep**. Fhirworx is the only design
(compared against awesome-gitea's full theme list — Catppuccin, Rainnny
GitHub, lutinglt, Earl Grey, Dark Arc, etc.) that puts a *dark* navbar
over a *light* body. Every reference theme keeps both surfaces in the
same luminance class. Because of that, Gitea's base CSS doesn't anticipate
the inversion: any Fomantic class with `color: var(--color-text)` (e.g.
`.ui.button` for the hamburger `#navbar-expand-toggle`) leaks near-black
text into the dark navbar. The sweep at the end of theme-fhirworx.css
forces nav-text on every text/icon element inside `#navbar`, and flips
dropdown popouts back to the light body palette since they float over
the page, not the bar.
## Custom templates (still bind-mounted)
`custom/templates/home.tmpl` is the anonymous landing page. It overrides
upstream's stock dashboard for unauthenticated visitors and renders the
homelab service grid. It's bind-mounted via `compose.yml`, not baked in,
because it's content not theme — easier to edit without rebuilding.
## Compose wiring
```yaml
gitea:
build:
context: ./infra/gitea
args:
GITEA_VERSION: v1.25.4
image: fhirworx/gitea:v1.25.4
environment:
- GITEA__ui__THEMES=fhirworx
- GITEA__ui__DEFAULT_THEME=fhirworx
volumes:
- gitea_data:/var/lib/gitea
- gitea_config:/etc/gitea
- ./infra/gitea/custom:/var/lib/gitea/custom
```
`THEMES=fhirworx` (single option) — no gitea-auto/light/dark/protanopia
variants are exposed in the user appearance dropdown. fhirworx is the only
choice and it's the default. Per-user `theme` column in the postgres
`"user"` table should be set to `'fhirworx'`.
## What goes wrong if you bypass the build
Earlier iterations bind-mounted raw CSS files into stock
`gitea/gitea:1.25.4-rootless`. Two persistent failures:
- **Inode drift**: Docker's single-file bind mount tracks by inode. The
`Edit`/`Write` tools rewrite atomically, replacing the inode. The container
keeps pointing at the now-orphaned old inode and sees nothing change.
Required `docker restart` after every edit.
- **Cache + version-pinning**: The asset URL embeds Gitea's version
(`?v=1.25.4`). Browsers cache aggressively for 6h. Edits to the CSS file
don't change the URL → cache hit serves stale CSS forever (or until the
user knows to hard-refresh). On Cloudflare it's even longer.
Baking the theme into bindata sidesteps both. The CSS only changes when you
rebuild the image, which means the version string actually changes in the
binary's metadata, and there's no inode tracking to drift.