Skip to main content

Overview

Gitea is a lightweight, self-hosted Git service — repositories, pull requests, issues, and a built-in package registry — backed by PostgreSQL. This template deploys a single Gitea server with persistent storage, an automatically wired PostgreSQL database, a public HTTPS web UI with Git-over-HTTPS, and an optional Git-over-SSH endpoint.

Architecture

  • Gitea — Stateful, single-replica workload running the rootless image. Serves the web UI, Git-over-HTTPS, and the package registry on port 3000, plus the built-in SSH server on 2222.
  • PostgreSQL — Backing database provisioned from the postgres template as a subchart and connected to Gitea on startup.

What Gets Created

  • Stateful Gitea Workload — The Gitea server with configurable CPU and memory, bootstrapped with an admin account on first boot.
  • Stateful PostgreSQL Workload — Single-replica Postgres, automatically connected to Gitea.
  • Volume Sets — A persistent volume set for Gitea (/var/lib/gitea: repositories, LFS objects, attachments, and SSH host keys) and one for PostgreSQL data, both with optional autoscaling.
  • Secrets — A dictionary secret holding the stable app secrets and admin credentials, an opaque secret holding the admin-bootstrap script, and the PostgreSQL credentials secret.
  • Identity & Policy — An identity bound to the Gitea workload with reveal access scoped to exactly its two secrets plus the PostgreSQL config secret.
  • Direct Load Balancer (optional) — A raw-TCP port for Git-over-SSH, created only when ssh.enabled is true.
This template does not create a GVC. You must deploy it into an existing GVC.

Prerequisites

None for a default install. Before installing, change the admin password and generate the three security values (see Important Notes). Install using your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

Key configuration values (see the template’s values.yaml for the complete set):

Image and Resources

  • image — The Gitea image. The template uses the rootless variant, which runs as UID 1000 and serves SSH on port 2222 inside the container.
  • resources — Min/max CPU and memory bounds for the Gitea workload.

Storage

  • volumeset.capacity — Initial Gitea volume size in GiB (minimum 10). Holds repositories, LFS objects, attachments, and SSH host keys.
  • volumeset.autoscaling.enabled — Automatically expand the volume as it fills. When enabled:
    • maxCapacity — Maximum volume size in GiB.
    • minFreePercentage — Trigger a scale-up when free space drops below this percentage.
    • scalingFactor — Multiply the current capacity by this factor when scaling up.

Admin and Security

  • gitea.admin.username / gitea.admin.password / gitea.admin.email — The site administrator account, bootstrapped on first boot. Change the password before installing.
  • gitea.security.secretKey / internalToken / jwtSecret — Stable per-install app secrets. Generate each with gitea generate secret SECRET_KEY (and INTERNAL_TOKEN, JWT_SECRET). These are values (not auto-generated) so they stay stable across upgrades. Never rotate secretKey after install — doing so makes all encrypted data (2FA secrets, tokens, mirror credentials) permanently unreadable.
  • gitea.disableRegistrationtrue (default) restricts new accounts to admin invites; false allows open self-registration.

Access

  • publicAccess.enabled — Exposes the HTTPS web UI, Git-over-HTTPS, and the package registry on the auto-assigned *.cpln.app canonical endpoint.
  • ssh.enabled — Exposes Git-over-SSH via a direct TCP load balancer. OFF by default — see Important Notes for the trade-off with the public web UI.
  • ssh.externalPort — The public SSH port clients connect to; also advertised in SSH clone URLs (default 22).
  • ssh.domain — The SSH host advertised in clone URLs. Empty uses the web domain.
  • internalAccess.type — Controls which workloads can reach Gitea over the internal network (none, same-gvc, same-org, or workload-list).

Backing Database

  • postgres.config.username / password / database — Credentials for the bundled PostgreSQL, applied on first startup. Change the password before deploying to production.
  • postgres.resources — Min/max CPU and memory bounds for the PostgreSQL workload.
  • postgres.volumeset.capacity — Initial Postgres volume size in GiB (minimum 10).
  • postgres.internalAccess.type — Controls which workloads can reach PostgreSQL.
PostgreSQL credentials are only applied on first startup when the data directory is empty. Changing them after the initial deployment has no effect on the running database — use PostgreSQL’s native commands (e.g. ALTER USER) instead.

Connecting

Open the canonical endpoint in a browser and sign in with the admin credentials to create repositories, users, and organizations. Clone and push over HTTPS using the same endpoint.

The SSH / HTTPS Endpoint Trade-off

A Control Plane workload has exactly one *.cpln.app canonical endpoint, and it can serve either the HTTPS web UI (web UI + Git-over-HTTPS on port 443) or a raw-TCP load balancer for SSH (port 22) — not both. Enabling ssh.enabled repoints that single endpoint to SSH, which takes the public web UI on 443 offline. Because of this, ssh.enabled is false by default, which keeps the public web UI and Git-over-HTTPS working out of the box — all most users need. Git-over-HTTPS supports full clone, push, and pull, so SSH is not required for normal use.
Enable ssh.enabled: true only if you either (a) serve the web UI through a custom domain (so the canonical endpoint is free for SSH), or (b) only need Git-over-SSH. Turning it on repoints the public *.cpln.app endpoint to SSH on port 22 and makes the public HTTPS web UI on 443 unreachable.

Important Notes

  • Change gitea.admin.password and the three gitea.security.* values before installing. The shipped defaults are illustrative placeholders and are insecure as-is. Generate each security value with gitea generate secret SECRET_KEY (and INTERNAL_TOKEN, JWT_SECRET).
  • Never rotate gitea.security.secretKey after install. Changing it makes all encrypted data (2FA secrets, tokens, mirror credentials) permanently unreadable. Because it is a value rather than auto-generated, helm upgrade keeps it stable.
  • Public SSH and the public web UI cannot share one endpoint — SSH is off by default. See The SSH / HTTPS Endpoint Trade-off above.
  • Single replica only. A rolling restart or upgrade incurs brief downtime. Do not raise the workload scale above 1 — replicas would each get separate repo volumes and corrupt state.
  • Data lives on the volume set and survives redeploys under the same release name. Change admin credentials after first boot in the Gitea UI, not via values — the data directory keeps the original account. To fully reset, helm uninstall (which deletes the volume set) then reinstall.

External References

Gitea Documentation

Official Gitea product documentation

Configuration Cheat Sheet

Full reference of Gitea configuration options

Package Registry

Using Gitea’s built-in package registry

Gitea Template

View the source files, default values, and chart definition