Gitea Kubernetes Deployment Architecture

Gitea stands as a premier open source, self-hosted git repository solution, distinguished by its powerful web user interface and a comprehensive suite of collaborative features. Beyond simple version control, Gitea integrates bug tracking, code review, and continuous integration capabilities, making it a robust alternative for organizations seeking full sovereignty over their source code and development workflows. When deployed within a Kubernetes environment, Gitea transforms from a simple application into a scalable, resilient service capable of handling varying loads through container orchestration.

The deployment of Gitea on Kubernetes can be approached through multiple strategies, ranging from native YAML manifests for those who prefer granular control over every object to Helm Charts for those seeking standardized, templated installations. Because Gitea is packaged as an official Docker image, it integrates seamlessly into the Kubernetes ecosystem, allowing for rapid scaling and standardized lifecycle management. For users who do not yet possess a functional Kubernetes cluster, projects like Imixs-Cloud provide a pathway to establishing the necessary infrastructure.

Integrating Gitea into a cluster necessitates a deep understanding of persistent storage, as Git repositories and configuration files must persist across pod restarts and rescheduling events. Furthermore, the networking layer must be carefully configured to handle both standard HTTP/HTTPS traffic for the web UI and SSH traffic for git operations. Whether utilizing the Enterprise edition for premium features or the community open-source version, the underlying architectural requirements remain consistent: a reliable container runtime, persistent volume claims, and an ingress controller to manage external access.

Hardware Resource Planning and Scaling

The allocation of resources for a Gitea installation on Kubernetes is not a one-size-fits-all process. Hardware requirements scale linearly with the expected user base and the volume of repositories hosted. Proper sizing prevents performance degradation and ensures that the Kubernetes scheduler can effectively place pods on nodes without causing resource exhaustion.

The following table outlines the recommended hardware specifications based on the size of the organization or team:

Team Size (Approx.) Memory CPU Cores SSD Capacity
~10 users 2-4 GB 2-4 cores 50-100 GB
~100 users 4-8 GB 4-8 cores 200-500 GB
~1000 users 16-32 GB 8-16 cores 2-5 TB

Under-provisioning memory can lead to Out-Of-Memory (OOM) kills, especially during heavy git-push operations or when the web UI is indexing large repositories. CPU cores directly impact the responsiveness of the web interface and the speed of Git operations. The storage capacity requirement is primarily driven by the size of the repositories; using SSDs is critical to ensure low-latency I/O for the underlying Git data structures and the database.

Prerequisites for Cluster Integration

Before initiating the deployment, certain software and environmental conditions must be met to ensure a successful installation. The infrastructure must support modern Kubernetes standards to avoid compatibility issues with the Gitea container image and the Helm charts.

  • Kubernetes 1.24+ cluster. This version ensures compatibility with the required API versions and storage primitives.
  • Persistent storage support. The cluster must have a configured StorageClass to dynamically provision volumes for Git data and database files.
  • Ingress support. An Ingress controller must be present to route external traffic into the cluster.
  • kubectl. The command-line tool must be installed and properly configured to target the specific cluster.
  • Helm 3. The package manager is required for the standard deployment path.
  • Container registry access. If the cluster is in a restricted environment, access to a registry capable of pulling the commitgo/gitea-ee image is necessary.
  • Enterprise License (Optional). For Gitea Enterprise, a license is required to unlock premium features; this can be requested via trial and uploaded post-deployment.

It is important to note that Git is bundled inside the Enterprise container image. This eliminates the need for administrators to install additional Git packages on the Kubernetes worker nodes, as the binary runs entirely within the isolated container environment.

Deployment Methodology: Helm vs. Native YAML

There are two primary paths for deploying Gitea on Kubernetes: the Helm Chart approach and the native YAML manifestation approach. Each serves different user profiles and operational goals.

Helm Chart Implementation

Helm provides a templated approach that simplifies the installation of Gitea and its dependencies. A non-customized installation can be triggered with the following sequence:

  • Add the repository: helm repo add gitea-charts https://dl.gitea.com/charts/
  • Update the repository: helm repo update
  • Install the release: helm install gitea gitea-charts/gitea

While Helm simplifies the initial setup, it can introduce complexity in production environments. The default Helm charts often install Redis and PostgreSQL through Bitnami charts. While this is convenient for "Day 1" operations, it can become difficult to manage for "Day 2" operations, such as database scaling, backup rotations, and complex migrations.

Native YAML Implementation

For users who prefer to avoid the abstraction of Helm, a native deployment strategy using YAML files allows for total control. This approach involves separating the configuration into logically distinct files to maintain organization:

  • 010-deployment.yaml: Handles the namespace and the Deployment object.
  • 020-volumes.yaml: Manages the PersistentVolumeClaims and storage mapping.
  • 030-network.yaml: Defines the Services and Ingress rules.

In a native deployment, the Deployment object defines the container image (e.g., gitea/gitea:1.13.2) and exposes the necessary ports. Gitea utilizes port 3000 for HTTP traffic and port 22 for Git-SSH. The container must mount a volume at /data to ensure that the repository data is not lost when the pod is terminated.

Gitea Enterprise Configuration and Deployment

Deploying the Enterprise version of Gitea requires a more structured approach to handle licensing and advanced configurations. This process involves the use of the commitgo/gitea-ee image and specific values files.

The initial step involves creating a dedicated namespace and managing secrets for the administrative account:

  • Create namespace: kubectl create namespace gitea
  • Create admin secret: kubectl -n gitea create secret generic gitea-admin --from-literal=username=admin --from-literal=password='replace-with-strong-password'

Following this, a values-enterprise.yaml file must be constructed. This file defines the core operational parameters of the instance:

yaml image: registry: docker.io repository: commitgo/gitea-ee tag: 25.4.3 rootless: true pullPolicy: IfNotPresent service: http: type: ClusterIP ssh: type: ClusterIP ingress: enabled: true annotations: kubernetes.io/ingress.class: <your-ingress-class> hosts: - host: gitea.example.com paths: - path: / pathType: Prefix tls: - secretName: gitea-tls hosts: - gitea.example.com gitea: admin: existingSecret: gitea-admin config: server: DOMAIN: gitea.example.com ROOT_URL: https://gitea.example.com/ persistence: size: 20Gi storageClass: standard

Once the values file is prepared, the installation is executed via the following command:

helm upgrade --install gitea gitea-charts/gitea --namespace gitea -f values-enterprise.yaml

Verification of the deployment is performed using kubectl -n gitea get pods and kubectl -n gitea get ingress to ensure the service is reachable and the pods are in a Running state.

Database Management and the PostgreSQL Challenge

The choice of database is critical for Gitea's performance and reliability. While Gitea supports various backends, PostgreSQL is a common choice. However, deploying PostgreSQL within Kubernetes—especially when using operators like the Percona Operator for PostgreSQL—introduces specific permission challenges.

The Percona Operator Approach

To avoid the management overhead of standard Helm-based database installations, the Percona Operator can be used:

  • Install operator: helm install my-operator percona/pg-operator

This operator provides a more robust framework for database management, but it introduces a critical "caveat" regarding user permissions starting with PostgreSQL version 15.

The PostgreSQL 15 Permission Issue

In PostgreSQL 15, the CREATE permissions were revoked from all users except the database owner within the public (or default) schema. This change leads to a catastrophic failure during the Gitea migration process. The error manifests in the logs as follows:

2024/09/03 16:35:38 cmd/migrate.go:40:runMigrate() [F] Failed to initialize ORM engine: migrate: sync: pq: permission denied for schema public

When this occurs, the Gitea init-container will fail to initialize the ORM engine and will repeatedly attempt to restart. To resolve this, the administrator must explicitly create a database user and grant the necessary permissions to that user to allow the Gitea migration tool to create the required tables within the public schema.

Health Monitoring and Liveness Probes

Ensuring the availability of Gitea is achieved through the implementation of Kubernetes liveness and readiness probes. Gitea provides a dedicated health check endpoint at /api/healthz.

A properly configured liveness probe ensures that Kubernetes can detect if the Gitea application has entered a deadlocked state or has crashed internally, prompting an automatic restart of the pod.

The recommended configuration for the liveness probe is as follows:

yaml livenessProbe: httpGet: path: /api/healthz port: http initialDelaySeconds: 200 timeoutSeconds: 5 periodSeconds: 10 successThreshold: 1 failureThreshold: 10

The initialDelaySeconds is set to 200 to allow the Gitea application sufficient time to initialize and run any pending database migrations before the probe begins testing. A successful health check returns an HTTP 200 OK response with a JSON body detailing the status of internal components:

json { "status": "pass", "description": "Gitea: Git with a cup of tea", "checks": { "cache:ping": [ { "status": "pass", "time": "2022-02-19T09:16:08Z" } ], "database:ping": [ { "status": "pass", "time": "2022-02-19T09:16:08Z" } ] } }

This detailed health response allows administrators to pinpoint whether a failure is related to the cache, the database, or the application core.

Architectural Analysis of Gitea on Kubernetes

The deployment of Gitea on Kubernetes represents a shift from monolithic hosting to a cloud-native architecture. By decoupling the application logic from the data layer, Gitea achieves a level of flexibility that is impossible in traditional VM-based setups.

The transition to a containerized environment introduces a critical dependency on the storage layer. Because Git is fundamentally a file-based system, the performance of Gitea is heavily gated by the I/O capabilities of the PersistentVolumes. In a Kubernetes environment, the choice between local PVs, network-attached storage, or managed cloud disks will directly influence the "git clone" and "git push" latency experienced by developers.

Furthermore, the separation of the deployment into distinct YAML files or the use of Helm values files enables a GitOps workflow. When the configuration is stored in a repository, changes to the Gitea environment—such as upgrading the image tag from 25.4.3 to a newer version—can be managed through pull requests and automated CI/CD pipelines. This reduces the risk of manual configuration drift across different environments (development, staging, production).

The intersection of PostgreSQL 15 and Gitea highlights a common challenge in the Kubernetes ecosystem: the friction between updated security defaults in upstream software and the expectations of application migration scripts. The requirement to manually grant schema permissions proves that "automated" deployments still require expert oversight to navigate the nuances of database security.

Ultimately, Gitea on Kubernetes provides a scalable, professional-grade version control system. By leveraging the Percona Operator for database reliability, implementing liveness probes for stability, and carefully sizing hardware for the user base, organizations can build a self-hosted Git infrastructure that rivals managed services in both performance and reliability.

Sources

  1. ralph.blog.imixs.com
  2. dev.to
  3. docs.gitea.com - Enterprise Installation
  4. docs.gitea.com - Kubernetes Installation

Related Posts