Skip to content

Gitea

Source control. The organisation standard; interact with it via the tea CLI, never gh.

Runtime Container (Docker Swarm), 2 containers: app, postgresql
Tier Core
Node swarm-core
Image gitea/gitea:1.27.0; postgres:16-alpine
URL https://gitea.lab.riversfamily.uk
Auth Native OIDC (manual bootstrap, see below)
Source ansible/stacks/core/gitea/

Configuration

SSH is explicitly disabled (GITEA__server__DISABLE_SSH=true): Traefik is the only service publishing host ports, so git-over-SSH has no port to use. Git is served over HTTPS through Traefik instead. Self-registration is disabled (GITEA__service__DISABLE_REGISTRATION=true).

OIDC auto-registration is enabled (GITEA__oauth2_client__ENABLE_AUTO_REGISTRATION=true, ACCOUNT_LINKING=auto, username claim preferred_username).

Volumes

Volume Path Backing Contents
data /data Local Repositories and app.ini — never NFS
database /var/lib/postgresql/data Local Postgres data — never NFS
(rendered) /oidc-bootstrap.sh Read-only Bootstrap script, see Gotchas

Networking

gitea joins both the shared traefik network (for its Traefik route) and this stack's private internal network. postgresql joins internal only — it is unreachable from every other stack.

Secrets

Vault variable Delivered as Purpose
vault_gitea_postgres_password Swarm secret Postgres password
vault_gitea_secret_key Swarm secret Gitea's internal secret key
vault_gitea_oidc_client_secret Baked into the rendered oidc-bootstrap.sh (mode 0750) OIDC client secret

Gotchas

  • OIDC login is not declarative. Unlike most other services, Gitea's OIDC auth source has no config-file or env-var surface, so oidc-bootstrap.sh.j2 must be run manually after deploy:
    docker exec -u git <gitea-task> sh /oidc-bootstrap.sh
    
    The script is idempotent (checks gitea admin auth list for an existing "authentik" source first) and polls (until gitea admin auth list; sleep 5) until Gitea's own DB migration has completed, since it can be run immediately after docker_stack deploy returns.
  • No depends_on: exists in Swarm compose files; the polling loop above is how this script tolerates Gitea not being ready yet, rather than relying on startup ordering.