Fanned out 5 read-only doc-auditor subagents (one per service group) that fact-checked the knowledge base against the live system + repo config, researched official setup docs online, and verified progress. Applied: - All 34 broken links fixed (real pages / external URLs / correct relative paths); 0 broken links remain. No .AGENTTRASH links (the 4 mentions are accurate descriptive text, not links). - Fact-check fixes: Readarr retired (May 2026), Radarr v4->v6, Calibre 9.2.1 live, Calibre-Web 0.6.25 live, Copyparty v1.20.21, LLM index ncmoe 38 + 786432 ctx, frank-default-small active (not frank-pp-worker), Hermes/SearXNG/Grafana hostnames, Loki/Alloy local images, Observability diagram (Promtail->Alloy), VLLM retired note, DFlash status, benchmark live-drift notes, Homepage test count 116.
98 lines
5.9 KiB
Markdown
98 lines
5.9 KiB
Markdown
# Gitea
|
|
|
|
Gitea is a self-hosted Git service with issues, pull requests, and a web UI. On Dankclaw it runs as three Quadlet-managed containers in the rootless podman session of user `dank`.
|
|
|
|
**Host:** Dankclaw — **LAN access:** `http://dankclaw:3000` (or `http://192.168.0.143:3000`) — **Public domain:** `gitea.franksdank.cloud` (DNS pending) — **Docs:** https://docs.gitea.com
|
|
|
|
## Containers
|
|
|
|
| Container | Unit | Image | Purpose |
|
|
|-----------|------|-------|---------|
|
|
| `gitea-postgres` | `gitea-postgres.service` | `docker.io/library/postgres:16-alpine` | Database |
|
|
| `gitea-server` | `gitea-server.service` | `docker.io/gitea/gitea:latest` | Web UI, API, git (HTTP :3000, SSH :2222) |
|
|
| `gitea-caddy` | `gitea-caddy.service` | `docker.io/library/caddy:latest` | Reverse proxy for the public domain |
|
|
|
|
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. The automatic `podman` default network has DNS disabled. Do not run the Gitea containers on it.
|
|
|
|
## Hosted repositories
|
|
|
|
| Repository | Purpose |
|
|
|------------|---------|
|
|
| `dank/serverAppConfigs` | this repo — Podman stacks + LLM fleet |
|
|
| `dank/vllmScripts` | retired 2026-08-22 — merged into `dank/serverAppConfigs` (history preserved) |
|
|
|
|
The LLM fleet knowledge base: [docs/LLM/index.md](../LLM/index.md)
|
|
|
|
## Management
|
|
|
|
Run all commands as `dank` on Dankclaw.
|
|
|
|
| Action | Command |
|
|
|--------|---------|
|
|
| Start all | `systemctl --user start gitea-postgres gitea-server gitea-caddy` |
|
|
| Stop all | `systemctl --user stop gitea-caddy gitea-server gitea-postgres` |
|
|
| Restart Gitea only | `systemctl --user restart gitea-server` |
|
|
| Status | `systemctl --user status gitea-postgres gitea-server gitea-caddy` |
|
|
| 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]
|
|
S --> C[gitea-caddy.service]
|
|
```
|
|
|
|
## Boot persistence
|
|
|
|
User-level linger is enabled for `dank` (`loginctl enable-linger dank`). The units start at host boot without a login session. Each unit carries `[Install] WantedBy=default.target`. The podman generator applies it at boot; no symlink is needed.
|
|
|
|
The containers use the quadlet fresh-start model. A stop removes the container (`podman run --rm --replace`). The next start recreates it. The bind-mounted data survives.
|
|
|
|
## Secrets
|
|
|
|
The database password lives in `/opt/gitea/.env` on the host (mode 0600). The quadlet files reference it with `EnvironmentFile=`. 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 `/opt/gitea/.env` 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,caddy}.container`, `gitea.network` | [`dankclaw/gitea/quadlet/`](../../dankclaw/gitea/quadlet/) |
|
|
| Caddyfile | `/opt/gitea/data/caddy/Caddyfile` | host-only (not in repo) |
|
|
| Secrets | `/opt/gitea/.env` (0600) | [`dankclaw/gitea/.env.example`](../../dankclaw/gitea/.env.example) |
|
|
|
|
After editing a repo copy, copy it to the target, then run `systemctl --user daemon-reload` and restart the affected units.
|
|
|
|
## Data volumes
|
|
|
|
| Container path | Host path | Contents |
|
|
|----------------|-----------|----------|
|
|
| `/data` | `/opt/gitea/data/gitea-gitea` | Git repositories, app.ini, attachments |
|
|
| `/var/lib/postgresql/data` | `/opt/gitea/data/gitea-postgres` | PostgreSQL data |
|
|
| `/etc/caddy/Caddyfile`, `/root/.local/share/caddy` | `/opt/gitea/data/caddy/...` | Caddy config and TLS state |
|
|
|
|
Back up `/opt/gitea/data/` (tar) or `pg_dump` the database. See the knowledge base page [[Gitea]].
|
|
|
|
## Gotchas
|
|
|
|
- **app.ini wins over env vars.** Gitea writes `/data/gitea/conf/app.ini` (host: `/opt/gitea/data/gitea-gitea/gitea/conf/app.ini`) on first start. The `[database] HOST` and `PASSWD` lines persist and override the `DATABASE_HOST`/`DATABASE_PASSWD` env vars. When you rename the database container, edit the `HOST` line.
|
|
- **The files in the data directory are owned by host UID 100999**, not `dank` (rootless ID mapping: container uid 1000 → host 100999). Edit them inside the container with `podman exec --user 1000 gitea-server ...`.
|
|
- **The host auto-reboots.** `unattended-upgrades` reboots Dankclaw when a package needs it. The quadlet units make Gitea survive that. See the 2026-08-16 incident below.
|
|
- **Port 3000 vs 3001.** The live host port is 3000. The full-stack [`dankclaw/compose.yaml`](../../dankclaw/compose.yaml) maps 3001. Align the two before deploying the full stack.
|
|
- **Legacy compose retired.** `/opt/gitea/podman-compose.yml` is retired to `/opt/gitea/.deprecated/`. Do not run it. Its containers collide with the quadlet units on ports 3000, 2222, 80, and 443.
|
|
- **Rootless cannot bind ports below 1024 by default.** `gitea-caddy` publishes 80 and 443. Without a host sysctl, `rootlessport` fails with `permission denied` and the unit crash-loops under `Restart=always`. The fix is a one-time sysctl: `net.ipv4.ip_unprivileged_port_start=80`, persisted in `/etc/sysctl.d/99-rootless-ports.conf`. Applied 2026-08-18 after a 13,000-restart crash loop.
|
|
|
|
## 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)
|