Install and Configure Gitea Git Service on Kubernetes / OpenShift

Posted on 256 views

Gitea is an open-source self-hosted private Git repository. You can host your own git repositories within Gitea, which ships with a good UI that is as interactive as the legendary Github.

Some of the features of Gitea include:

  • User dashboard – Users can view commits, clone, report issues, navigate through organizations etc.
  • Issues dashboard – Users can raise issues, view open and closed issues. They can also take part in the resolution of issues by commenting.
  • Pull requests
  • Maintain versions through releases.
  • Monitor the repo activities.
  • etc.

This article will cover how to install and configure Gitea on Kubernetes. There are a number of methods that can be used to deploy Gitea on your Kubernetes/OpenShift cluster running either on premise or in the cloud.

Gitea can be installed on your Kubernetes/Openshift cluster in two different ways:

  1. Using Helm chart
  2. Using Custom deployment.

We shall cover the installation using both methods.

Option 1: Install Gitea on Kubernetes using Helm Chart

Before you can use this method, make sure you have the prerequisites below checked:

  • Kubernetes 1.12+
  • Helm 3.0+
  • PV provisioner for persistent data support

Note that you need a persistent volume (PV) for this kind of deployment as it is stateful. In our previous article we covered how to provision persistent volumes in a Kubernetes cluster using OpenEBS. Make sure you go through it to provision storage classes and persistent volumes.

Check the version of Helm running on your system:

helm version

Add Gitea Helm repo to your system:

 helm repo add gitea-charts

Install Gitea using Helm:

 helm install gitea gitea-charts/gitea

A successful install will give you an output as one below:

root@bazenga:~# helm install gitea gitea-charts/gitea 
NAME: gitea-repo
LAST DEPLOYED: Fri Jun 18 23:11:07 2021
NAMESPACE: default
STATUS: deployed
1. Get the application URL by running these commands:
  echo "Visit to use your application"
  kubectl --namespace default port-forward svc/gitea-repo-http 3000:3000

To expose the deployment using NodePort, you will need to create a gitea-values.yaml file that will specify the NodePort then parse the new values along with the installation script.

vim gitea-values.yaml

Add the NodePort Values:

    type: ClusterIP
    port: 3000

Run the installation along with the YAML file:

helm install --values gitea-values.yaml gitea gitea-charts/gitea

Confirm that the NodePort service has been created once the installation is done:

kubectl get svc

Sample output:

root@bazenga:~# kubectl get svc
NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
gitea-http                  NodePort           3000:32190/TCP   10s
gitea-memcached             ClusterIP            11211/TCP        10s
gitea-postgresql            ClusterIP           5432/TCP         10s
gitea-postgresql-headless   ClusterIP   None                    5432/TCP         10s
gitea-ssh                   ClusterIP           22/TCP           10s

We can confirm that the gitea-http service has been exposed by NodePort on port 32190.

You might want to do some modifications to your deployment e.g selecting a different StorageClass and PersistentVolumeClaim. Otherwise Gitea creates a persistent volume from the default StorageClass in your system.

Deploy and Use OpenEBS Container Storage on Kubernetes

You can check the default StorageClass in your cluster by running the command below:

kubectl get sc



You will then identify the storage class that is marked with “(default)” which means that it is your default SC. This SC should be able to provision dynamic volumes. I have deployed OpenEBS container storage in my cluster and that is what I use for the dynamic volume provisioning.

Deploy and Use OpenEBS Container Storage on Kubernetes

You can check and confirm if the deployment has been successful by checking the status of the deployed pod(s)

kubectl get pod | grep gitea

Sample output:

root@bazenga:~# kubectl get pod | grep gitea
gitea-repo-0                            1/1     Running   0          7m23s
gitea-repo-memcached-655769f459-65wdd   1/1     Running   0          7m23s
gitea-repo-postgresql-0                 1/1     Running   0          7m23s

In my deployment, three pods were deployed and are all running successfully.

Option 2: Install Gitea on Kubernetes using Manual Deployment

This is another alternative for Gitea deployment where you have to specify the deployment in a YAML file. This is much easier if you want to specify some parameters before deploying.

You will also need a persistent volume for this kind of deployment.

Create a deployment with the details below:

vim gitea-deploy.yaml

Add the content below modifying the volume details to fit your environment:

apiVersion: apps/v1
kind: Deployment
  name: gitea
    app: gitea
  replicas: 1
      app: gitea
        app: gitea
      - name: gitea
        image: gitea/gitea:latest
        - containerPort: 3000
          name: gitea
        - containerPort: 22
          name: git-ssh
        - mountPath: /data
          name: git-volume
      - name: git-volume
          claimName: git-volume

apiVersion: v1
kind: PersistentVolumeClaim
  name: git-volume
    - ReadWriteOnce
      storage: 2Gi

In the above deployment, we have created a stateful deployment which makes use of a 2GB volume which will be dynamically created by the PersistenVolumeClaim. The volume will be mounted at /data of the container.

Apply the deployment to setup Gitea manually.

kubectl apply -f gitea-deploy.yaml

You will notice that a new deployment is created, which creates the Gitea pod, PVC and persistent volume. The volumes are created from the default StorageClass. Else, you will have to specify the SC from which the PersistentVolume shall be created.

Expose Gitea Deployment Using NodePort

There are different methods of exposing a deployment, you can choose to use NodePort, Port-forwarding, LoadBalancer, http ingress, etc. We shall be exposing our deployent using Nodeport. To do so, run the command below:

kubectl expose deploy gitea --port 3000 --type NodePort

This is because Gitea http service runs on port 3000.

You can then obtain the exposed service port through:

kubectl get svc

Sample Output:

[email protected]:~# kubectl get svc
NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
gitea                            NodePort            3000:31749/TCP   4h12m

This means that our deployment has been exposed on port 31749 using NodePort service.

Access Gitea Web UI from your Browser

The next step will be to access the Gitea web UI to proceed with the setup.

This can be done through accessing any of the Kubernetes worker nodes and the NodePort that was exposed.

You can get the details of the nodes through the command:

kubectl get nodes -o wide

This is how my nodes look like:

[email protected]:~# kubectl get nodes -o wide
node01   Ready    control-plane,master   2d    v1.21.1           Debian GNU/Linux 10 (buster)   4.19.0-16-amd64   docker://20.10.7
node02   Ready                     2d    v1.21.1           Debian GNU/Linux 10 (buster)   4.19.0-16-amd64   docker://20.10.7
node03   Ready                     2d    v1.21.1           Debian GNU/Linux 10 (buster)   4.19.0-16-amd64   docker://20.10.7

You can access the node using the “INTERNAL-IP” or map the IPs in the /etc/hosts.

Navigate to http://worker-node-IP:NodePort. e.g:

You will get to the Gitea home page:


Click on any button and you will be redirected to the initial setup page where you will be required to setup the initial configurations. Select the database that you want to use(preferably SQLite) , Site title.


Modify the “Gitea Base URL” to have the URL of your worker node and the NodePort e.g for my case.


Then Install Gitea.

Since this is a new setup, we need to create the admin user for our repository. Click on the “Register” button at the top-right to create a user account.


When the details have been captured, you will be redirected to an empty dashboard as shown below:


We can now proceed to creating a new repository by clicking on the (+) sign at the top-right then choose “+New Repository”


Give the repo a name and choose if you want it to be private or public. Then create the repo.

You will be redirected to the interface such as this below:


In my case, I created a repo called test. We can now start using our repo using the normal Git syntax such as push, clone etc.

We can clone the git test repository that we created by :

git clone http://node02:31749/gitadmin/test.git

Then initialize our repository and update the repo:

git init

git add
git commit -m "first commit"
git remote add origin [email protected]:gitadmin/test.git
git push -u origin master

We can now see that the repo has been updated as per the screenshot below:


We can also see that the changes are visible and the repo is ready to use.


We can test the volume persistence by deleting the pod on which Gitea is running. This will cause Kubernetes to reschedule another pod. If the persistent volume is in place, the data saved from the previous port will be retained, otherwise, you will be redirected to a fresh Gitea initial setup.

Get the running port and identify the Gitea pod:

kubectl get pod

Sample output:

root@bazenga:~# kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
gitea-0                           1/1     Running   0          39m
gitea-memcached-c8547c9c9-jvcn9   1/1     Running   0          39m
gitea-postgresql-0                1/1     Running   0          39m

Delete the Gitea pod:

kubectl delete pod gitea-0

Check the status of the pods to see if the pod restarted:

root@bazenga:~# kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
gitea-0                           1/1     Running   0          25s
gitea-memcached-c8547c9c9-jvcn9   1/1     Running   0          43m
gitea-postgresql-0                1/1     Running   0          43m

You can notice the age of the pod gitea-0. This confirms that the pod has restarted. Now login to the web UI and confirm if you can still get access the repositories that you had updated before. This will be proof enough that your volumes are persistent.

That is all on how to deploy Gitea on Kubernetes/OpenShift. I hope this guide was helpful. Cheers!


Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.