--- type: reference title: Gitea Architecture description: Gitea container architecture, network topology, and Caddy reverse proxy configuration on dankclaw. tags: - gitea - architecture verified: 2026-10-18 --- # Gitea Architecture Two quadlet-managed containers (Gitea, PostgreSQL) on a shared private Podman network (rootless, user `dank`). Gitea connects to PostgreSQL via network DNS. The fleet Caddy (separate stack, see [/caddy/index.md](/caddy/index.md)) proxies HTTP/S to Gitea — the old dedicated `gitea-caddy` container is retired. ## Network Topology ``` Client (HTTPS) ↓ caddy :80/:443 (auto-TLS via Let's Encrypt DNS-01/Porkbun) ↓ reverse_proxy 192.168.0.143:3000 (published quadlet port) gitea-server :3000 (web UI, API) ↓ PostgreSQL protocol gitea-postgres :5432 (internal only) ``` ## Network The containers share the quadlet network `systemd-gitea` (file `gitea.network`, DNS enabled by default). Container names resolve via network DNS. The automatic rootless `podman` default network has `dns_enabled: false`. Container names do not resolve there. Keep the Gitea stack on `systemd-gitea`. ## Container and Unit Names | Container | Unit | Depends on | |---|---|---| | `gitea-postgres` | `gitea-postgres.service` | `gitea-network.service` | | `gitea-server` | `gitea-server.service` | `gitea-postgres.service` | Podman 5.x names quadlet units after the file (`gitea-server.service`), with no `container-` prefix. ## Caddy Configuration Caddy is a separate quadlet-managed service (`caddy.container`) on the shared `dankclaw_default` network. The live Caddyfile at `/home/dank/Containers/caddy/Caddyfile` proxies Gitea via the published quadlet port: ``` gitea.franksdank.cloud { reverse_proxy 192.168.0.143:3000 } ``` - Caddy issues Let's Encrypt certs via DNS-01 (Porkbun module) — no inbound HTTP port needed. - Pi-hole quadlet resolves `gitea.franksdank.cloud` to `192.168.0.143` via `addn-hosts`. - Serves HTTP on port 80 and HTTPS on port 443, both bound to `0.0.0.0`. ## Gitea Configuration Quadlet file: `~/.config/containers/systemd/gitea-server.container` (repo copy: `serverAppConfigs/dankclaw/gitea/quadlet/gitea-server.container`) Key environment variables: - `DATABASE_TYPE=postgres` - `DATABASE_HOST=gitea-postgres` (network DNS) - `DATABASE_NAME=gitea` - `DATABASE_USER=gitea` - `DATABASE_PASSWD` from `/home/dank/Containers/gitea/env` (mode 0600) - `USER_UID=1000`, `USER_GID=1000` Gitea writes `/data/gitea/conf/app.ini` on first start (host: `/home/dank/Containers/gitea/data/gitea/conf/app.ini`). The `[database] HOST` and `PASSWD` lines in app.ini override the env vars. When you rename the database container, edit the `HOST` line in app.ini as well. ## Ports | Service | Host Binding | Container Port | Access | |---|---|---|---| | Gitea HTTP | `0.0.0.0:3000` | 3000 | Web UI, API | | Gitea SSH | `0.0.0.0:2222` | 22 | Git clone/push via SSH | | PostgreSQL | `5432` (internal) | 5432 | Container-to-container only | Note: the full-stack repo compose (`dankclaw/compose.yaml`) maps Gitea HTTP to host port 3001. The live stack uses 3000. Align before the full-stack deploy. `gitea.franksdank.cloud` resolves to `192.168.0.143` via the Pi-hole quadlet's `addn-hosts`. Caddy obtains Let's Encrypt certs via DNS-01 (Porkbun module), which requires no inbound port reachability. LAN clients reach Gitea via `http://dankclaw:3000` (published quadlet port). ## See Also - ](index.md) — index with management commands - [[management|management]] — operations, boot persistence, incident - [[data-persistence|data-persistence]] — volumes and backups