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
postgrestemplate 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
revealaccess 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.enabledistrue.
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’svalues.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 withgitea generate secret SECRET_KEY(andINTERNAL_TOKEN,JWT_SECRET). These are values (not auto-generated) so they stay stable across upgrades. Never rotatesecretKeyafter install — doing so makes all encrypted data (2FA secrets, tokens, mirror credentials) permanently unreadable.gitea.disableRegistration—true(default) restricts new accounts to admin invites;falseallows open self-registration.
Access
publicAccess.enabled— Exposes the HTTPS web UI, Git-over-HTTPS, and the package registry on the auto-assigned*.cpln.appcanonical 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 (default22).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, orworkload-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.
Important Notes
- Change
gitea.admin.passwordand the threegitea.security.*values before installing. The shipped defaults are illustrative placeholders and are insecure as-is. Generate each security value withgitea generate secret SECRET_KEY(andINTERNAL_TOKEN,JWT_SECRET). - Never rotate
gitea.security.secretKeyafter install. Changing it makes all encrypted data (2FA secrets, tokens, mirror credentials) permanently unreadable. Because it is a value rather than auto-generated,helm upgradekeeps 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