Files
Frank 327e78b950 docs(vault): destroy the dead weight — 53 pages and the change diary
The vault was 155 pages / 31,210 lines, most of it measurement ledgers for
payloads that no longer run. A throughput figure for a runtime nobody operates is
not a record: AI moves faster than the vault, so the number is wrong before
anyone reads it, and a wrong number in a runbook gets believed. Per the new
purpose test in `AGENTS.md` → *Documentation Policy*, it is destroyed.

Gone (`.AGENTTRASH/20261019-destruction/`, KILL-LIST.txt is the manifest):
- the `frank-medium` endpoint and its five era pages, `frank-npu`, FastFlowLM,
  the ikllama/kingjones/dealign/frank-redo eras, the ling/swift15/freetoken/ubatch
  campaign pages, qwen3.8 spec-matrix and strix-optimizations, the two
  "Running Qwen3.6 …" pages;
- the whole `Pipeline Parallelism/` folder (no live script passes a pipeline flag)
  and the multi-device/x4-pair/hybrid/offload experiment pages;
- every vLLM page — no vLLM endpoint exists on this fleet;
- `LLM/deployment.md` (`Architecture/Deployment Flow.md` is the test-referenced
  owner) and the external surveys (SGLang, Lemonade, llama.cpp forks/diff,
  self-hosted app census, the TTS survey) that were obsolete by construction;
- `log.md`, 2,380 lines. Git holds the chronology; a causal law belongs to the
  page that owns the thing it governs, never to a diary.

Survivors: 101 pages, 17,542 lines, 0 OKF violations, 0 unresolved links. Eras
tables keep the window, payload, runtime, reason and rollback pointer; the rate
columns are blanked. The live shapes stay verbatim — those numbers are what the
deployer and `models.yml` consume.
2026-10-19 10:56:37 -07:00

124 lines
9.1 KiB
Markdown

---
type: reference
title: Gitea
description: Gitea deployment on Dankclaw with its web UI reverse-proxied by the canonical Caddy service.
tags:
- gitea
- dankclaw
- quadlet
- caddy
timestamp: 2026-08-26
---
# Gitea
Gitea is a self-hosted Git service with issues, pull requests, and a web UI. On Dankclaw it runs as two Quadlet-managed containers in the rootless Podman session of user `dank`. The canonical Caddy on the same host reverse-proxies its web UI at `gitea.franksdank.cloud`.
**Host:** Dankclaw — **LAN access:** `http://dankclaw:3000` (or `http://192.168.0.143:3000`), git SSH on `2222` (`ss -ltnp` 2026-10-18) — **Proxy domain:** `gitea.franksdank.cloud` — **Docs:** https://docs.gitea.com
## Containers
| Container | Unit | Image | Purpose |
|-----------|------|-------|---------|
| `gitea-postgres` | `gitea-postgres.service` | `docker.io/library/postgres:16-alpine` (`dankclaw/gitea/quadlet/gitea-postgres.container:18`) | Database |
| `gitea-server` | `gitea-server.service` | `docker.io/gitea/gitea:latest` (`dankclaw/gitea/quadlet/gitea-server.container:22`) — answers `GET /api/v1/version` → `1.27.3` (2026-10-18) | Web UI, API, git (HTTP :3000, SSH :2222, `dankclaw/gitea/quadlet/gitea-server.container:32-33`) |
The containers share the private bridge network `systemd-gitea`. The quadlet network file `gitea.network` enables DNS, so the containers resolve each other by name; `podman network ls` 2026-10-18 confirms `systemd-gitea dns=true` while the automatic `podman` default network is `dns=false`. Do not run the Gitea containers on it.
## Hosted repositories
| Repository | Purpose |
|------------|---------|
| `dank/serverAppConfigs` | this repo — Podman stacks + LLM fleet |
| `dank/command-center` | second public repo on the instance (`GET http://127.0.0.1:3000/api/v1/repos/search` 2026-10-18) |
| `dank/vllmScripts` | retired 2026-08-22 — merged into `dank/serverAppConfigs` (history preserved) *(unverified 2026-10-18: the anonymous API search returns no match and `/dank/vllmScripts` is 404, so whether the repo still exists privately cannot be checked without a token)* |
The LLM fleet knowledge base:
## Management
Run all commands as `dank` on Dankclaw.
| Action | Command |
|--------|---------|
| Start all | `systemctl --user start gitea-postgres gitea-server` |
| Stop all | `systemctl --user stop gitea-server gitea-postgres` |
| Restart Gitea only | `systemctl --user restart gitea-server` |
| Status | `systemctl --user status gitea-postgres gitea-server` |
| Container logs | `podman logs -f gitea-server` |
| Unit logs | `journalctl --user -u gitea-server -f` |
The units start in dependency order:
```mermaid
graph LR
N[gitea-network.service] --> P[gitea-postgres.service]
P --> S[gitea-server.service]
```
## Boot persistence
User-level linger is enabled for `dank` (`loginctl enable-linger dank`; `loginctl show-user dank -p Linger` → `yes`, 2026-10-18). The units start at host boot without a login session. Each unit carries `[Install] WantedBy=default.target` with `Restart=always` (`dankclaw/gitea/quadlet/gitea-server.container:41,43-44`; `gitea-postgres.container:28,30-31`); live 2026-10-18 both report `systemctl --user is-enabled` → `generated` and `is-active` → `active`. The podman generator applies the install at boot; no symlink is needed.
The containers use the quadlet fresh-start model. A stop removes the container — the generated unit runs `podman run --name gitea-server --replace --rm …` with `ExecStopPost=-/usr/bin/podman rm -v -f -i gitea-server` (`systemctl --user cat gitea-server.service` 2026-10-18). The next start recreates it. The bind-mounted data survives. The canonical Caddy is managed separately by the Dankclaw stack.
## Secrets
The database password lives in `/home/dank/Containers/gitea/env` on the host
(mode 0600); `gitea-postgres.container` and `gitea-server.container` load it
via `EnvironmentFile=` (verified from the live units — the `${GITEA_DB_PASSWORD}`
placeholders are expanded by systemd at start). The password never enters this
repository. Placeholders live in
[`dankclaw/gitea/.env.example`](../../dankclaw/gitea/.env.example).
Do not change the password in place. Change the PostgreSQL role first, then
update the env file and the `[database] PASSWD` line in the app.ini (see
Gotchas), then restart the stack.
## Configuration files
| File | Location | Repo copy |
|------|----------|-----------|
| Quadlet units | `~/.config/containers/systemd/gitea-{postgres,server}.container`, `gitea.network` | [`dankclaw/gitea/quadlet/`](../../dankclaw/gitea/quadlet/) |
| Caddyfile | `/home/dank/Containers/caddy/Caddyfile` | [`dankclaw/Caddyfile`](../../dankclaw/Caddyfile) |
| Secrets | `/home/dank/Containers/gitea/env` (0600; loaded via `EnvironmentFile=`) | [`dankclaw/gitea/.env.example`](../../dankclaw/gitea/.env.example) |
After editing a repo copy, deploy through `scripts/deploy.sh dankclaw`. The Gitea database/server units are installed from this directory; the canonical Caddy and its rendered Caddyfile are deployed as the separate `caddy` service. Do not manually recreate the retired `gitea-caddy` unit.
## Data volumes
Per the live quadlet units (`Volume=` lines):
| Container path | Host path | Contents |
|----------------|-----------|----------|
| `/data` | `/home/dank/Containers/gitea/data` | Git repositories, app.ini, attachments (`dankclaw/gitea/quadlet/gitea-server.container:34`) |
| `/var/lib/postgresql/data` | `/home/dank/Containers/gitea/postgres` | PostgreSQL data (`dankclaw/gitea/quadlet/gitea-postgres.container:23`) |
Back up `/home/dank/Containers/gitea/` (tar) or `pg_dump` the database. See the knowledge base page [[Gitea]].
## Gotchas
- **Gitea's uid 1000 is NOT dank's host uid.** The units run podman in the user
manager with no `UserNS=`/`--user` override (`podman inspect gitea-server
--format '{{json .HostConfig.IDMappings}}'` → `null`, i.e. the default rootless
map), so container uid 1000 (the `git` user) lands on host uid **100999**
(the first subuid plus 999): `ls -ln /home/dank/Containers/gitea/data` shows
`git/` and `gitea/` owned by `100999` while `ssh/`, created host-side, is
`1000` (`ls -ln` 2026-10-18). Edit app data through the container instead of
the host path: `podman exec --user 1000 gitea-server ...`.
- **The host gets rebooted.** The 2026-08-16 incident below was an `unattended-upgrades` reboot; today `unattended-upgrades` is enabled but `Unattended-Upgrade::Automatic-Reboot` is not set anywhere in `/etc/apt/apt.conf.d/` (`apt-config dump` and `grep` 2026-10-18 — the key is present only commented-out at `50unattended-upgrades:94`). Do not rely on the trigger: the Quadlet units above are what make Gitea survive any reboot.
- **Port 3000, and one owner.** The live host ports are 3000 (HTTP) and 2222 (git SSH), published by the `gitea-server` Quadlet unit (`dankclaw/gitea/quadlet/gitea-server.container:32-33`; `ss -ltnp` 2026-10-18). The `dankclaw/compose.yaml` that mapped 3001 was **retired on 2026-09-16** (staged in `.AGENTTRASH/`) once an ownership audit showed every container on this host reports a `PODMAN_SYSTEMD_UNIT` label — a second composition path could only spawn a duplicate fighting a unit for a name. Do not reintroduce a compose service for Gitea or the proxy.
- **Legacy compose retired.** `/opt/gitea/podman-compose.yml` is retired to `/opt/gitea/.deprecated/` (`ls` 2026-10-18 shows the file there, 1,278 B). Do not run it. Its containers collide with the Quadlet units on ports 3000 and 2222.
- **Canonical proxy, and it is exempt.** `gitea.franksdank.cloud` is served by the canonical Caddy **unit** (`dankclaw/caddy/quadlet/caddy.container`, repo `dankclaw/Caddyfile`), which proxies to `192.168.0.143:3000` and is on the **exempt** list — no Anubis challenge, no Authentik gate — because git clients cannot solve a JS proof; Gitea's own login is the only gate. Do not recreate a Gitea-specific Caddy unit or publish another proxy on ports 80/443. If a legacy unit is ever installed again, the deployer stages it under `~/.AGENTTRASH/YYYYMMDD-gitea-caddy/` before starting canonical Caddy (`scripts/deploy-remote.sh:347,365-370`).
- **`/metrics` is off, so Prometheus cannot scrape Gitea.** `curl http://127.0.0.1:3000/metrics` → **404** and the container carries no metrics-related environment variable (`podman inspect gitea-server` filtered 2026-10-18; no `ENABLE_METRICS`/`PROMETHEUS` line in either quadlet). The `gitea` job (`shared/prometheus/prometheus.yml:46-49`, target `192.168.0.143:3000`, `metrics_path: /metrics`) is therefore DOWN with `server returned HTTP status 404 Not Found` (`/api/v1/targets` 2026-10-18). Gitea is covered by the homepage status probe, not by metrics.
## Incident: 2026-08-16 — down after unattended reboot
`unattended-upgrades` rebooted Dankclaw at 15:01 on 2026-08-16. The Gitea containers ran through podman-compose with `restart: unless-stopped` and no systemd units. Rootless podman does not auto-start containers at boot without units. Gitea stayed down until a manual start at 16:02. The fix: migrate the stack to quadlet units with linger (this page). After the fix, verify on the next reboot.
## See Also
- [[Dankclaw Stack]]
- [[Postgres]]
- Knowledge base: [[Gitea]] (tools)