`[[page|Label]]` is Obsidian syntax, not OKF. `kb-lint` resolves it Obsidian-style — by filename, anywhere in the bundle — so it has never tripped the link gate, while every other consumer of the bundle (an OKF renderer, a Gitea wiki export, `grep` for reachability) sees bracketed text where a link should be. That is how two generated pages ended up with no inbound link at all and nobody noticed: the my-first link census of the bundle reported them as orphans because their only inbound edges were wikilinks. Mechanical conversion, 52 links across 17 pages, each resolved against the same page set `kb-lint` uses: an explicit `|Label` is kept verbatim, an unlabelled link takes the target's frontmatter `title`. Targets are emitted bundle-absolute (`/tools/niri/tips.md`), the form the spec recommends and the form 99 existing links in this bundle already use. Two links were `[[index]]`, which resolves by filename to 21 pages — the ambiguity that filename-resolution invites. Both meant their own directory's index, so both are now written out in full: `/tools/gitea/index.md`, `/tools/niri/index.md`. The linter still tolerates wikilinks; whether it should reject them outright is an open question on #64, because that would replace the two tests pinning today's tolerance. Refs #64
107 lines
4.9 KiB
Markdown
107 lines
4.9 KiB
Markdown
---
|
|
type: reference
|
|
title: Gitea Management
|
|
description: Gitea container management, boot persistence, troubleshooting, upgrades, and backup procedures on dankclaw.
|
|
tags:
|
|
- gitea
|
|
- management
|
|
- quadlet
|
|
verified: 2026-10-18
|
|
---
|
|
|
|
# Gitea Management
|
|
|
|
All commands run as `dank` on dankclaw. The stack is quadlet-managed (since 2026-08-16). The legacy podman-compose file is retired to `/opt/gitea/.deprecated/`.
|
|
|
|
## Daily Operations
|
|
|
|
| Task | Command |
|
|
|---|---|
|
|
| Start all services | `systemctl --user start gitea-postgres gitea-server` |
|
|
| Stop all services | `systemctl --user stop gitea-server gitea-postgres` |
|
|
| Restart Gitea only | `systemctl --user restart gitea-server` |
|
|
| Follow container logs | `podman logs -f gitea-server` |
|
|
| Follow unit logs | `journalctl --user -u gitea-server -f` |
|
|
| Check status | `systemctl --user status gitea-postgres gitea-server` |
|
|
| Check health | `curl -s http://127.0.0.1:3000/api/v1/version` |
|
|
|
|
Start the stack in order (postgres, server). The unit dependencies enforce the order when you start a single unit, but starting all three explicitly avoids surprises.
|
|
|
|
## Boot Persistence
|
|
|
|
| Setting | Value | Check |
|
|
|---|---|---|
|
|
| Quadlet units | `~/.config/containers/systemd/gitea-{postgres,server}.container`, `gitea.network` | `systemctl --user list-units 'gitea*'` |
|
|
| Boot enablement | `[Install] WantedBy=default.target` in each file | `systemctl --user is-enabled gitea-server` (reports `generated`) |
|
|
| User linger | enabled for `dank` | `loginctl show-user dank \| grep Linger` |
|
|
|
|
At boot, systemd starts the user manager (linger), then `gitea-network.service`, then the containers in dependency order. No login session is required.
|
|
|
|
After editing a quadlet file: run `systemctl --user daemon-reload`, then restart the affected units.
|
|
|
|
## Config Files
|
|
|
|
| File | Path |
|
|
|---|---|
|
|
| Quadlet units | `~/.config/containers/systemd/gitea-*.container`, `gitea.network` |
|
|
| Secrets | `/home/dank/Containers/gitea/env` (mode 0600, `GITEA_DB_PASSWORD`) — quadlet `EnvironmentFile` |
|
|
| Gitea app config | `/home/dank/Containers/gitea/data/gitea/conf/app.ini` (container-owned, UID 100999) |
|
|
|
|
Repo copies: `serverAppConfigs/dankclaw/gitea/` (quadlet files, `.env.example`). Copy edits to the target, then `daemon-reload` + restart.
|
|
|
|
## Upgrades
|
|
|
|
1. Pull latest images: `podman pull docker.io/gitea/gitea:latest` (repeat per image)
|
|
2. Restart the stack: `systemctl --user stop gitea-server gitea-postgres && systemctl --user start gitea-postgres gitea-server`
|
|
3. Verify startup: `podman logs -f gitea-server`
|
|
|
|
Gitea handles database migrations automatically on startup. PostgreSQL version bumps require editing the image tag in `gitea-postgres.container`, then a dump/restore of the data (a fresh PostgreSQL does not read the old data directory format blindly).
|
|
|
|
## Troubleshooting
|
|
|
|
### Gitea cannot reach the database
|
|
|
|
Check the `[database] HOST` line in `/home/dank/Containers/gitea/data/gitea/conf/app.ini`. It must be `gitea-postgres:5432`. app.ini overrides the `DATABASE_HOST` env var.
|
|
|
|
Then check name resolution from the container:
|
|
|
|
```
|
|
podman exec gitea-server getent hosts gitea-postgres
|
|
```
|
|
|
|
If it fails, the containers are not on the `systemd-gitea` network. Check `podman inspect gitea-server --format '{{.NetworkSettings.Networks}}'`.
|
|
|
|
### Files in the data directory are not writable
|
|
|
|
Container-created files are owned by host UID 100999 (rootless ID mapping of container uid 1000). Edit them inside the container:
|
|
|
|
```
|
|
podman exec --user 1000 gitea-server vi /data/gitea/conf/app.ini
|
|
```
|
|
|
|
### Caddy 502s
|
|
|
|
The upstream `gitea-server:3000` is down or unresolvable. Start `gitea-server`, check its logs, and verify `/home/dank/Containers/caddy/Caddyfile` references `192.168.0.143:3000`.
|
|
|
|
### Container names do not resolve
|
|
|
|
The automatic rootless `podman` network has DNS disabled. Run the stack on `systemd-gitea` (see `gitea.network`). If the network state goes stale after a reboot, restart the stack; recreate the network only if restarts do not help.
|
|
|
|
## Incident Log
|
|
|
|
### 2026-08-16: down for ~1 hour after unattended reboot
|
|
|
|
`unattended-upgrades` rebooted dankclaw at 15:01. The legacy podman-compose stack had no systemd units. Rootless podman does not auto-start containers at boot without units. Gitea stayed down until a manual start at 16:02.
|
|
|
|
Fix: migrated the stack to quadlet units with `[Install] WantedBy=default.target` and enabled user-level linger. Also fixed two latent bugs found during the migration: the live Caddyfile upstream name (`server` → `192.168.0.143:3000`) and the stale `HOST = postgres:5432` line in app.ini (→ `gitea-postgres:5432`).
|
|
|
|
Verify the fix on the next host reboot.
|
|
|
|
## See Also
|
|
|
|
- ](index.md) — index
|
|
- [client-access](/tools/gitea/client-access.md) — how client hosts authenticate (token + credential store)
|
|
- [architecture](/tools/gitea/architecture.md) — network topology
|
|
- [data-persistence](/tools/gitea/data-persistence.md) — backups
|
|
- [containers](/engineering/infra/containers.md) — quadlet reference
|