Running Gitea on Kubernetes

Gitea is one of several notable self-hosted git solutions, but because it was seemingly lightweight to run (it’s a Go binary, and can also be delivered as a Docker image), and easy to configure, I decided I would try running it inside my cluster (alongside my registry, and other stateful services) as well.

Because my Git data is fairly sensitive, I decided to limit its scheduling to only nodes with adequate storage, and labeling those nodes:

kubectl label nodes <node name> git-data-storage=true 

These nodes I configured to have particularly durable, large volumes attached to the hosts, and so when I schedule on those nodes, applications requiring storage can just use hostPath type volumes to store their data.

I start with a fairly typical deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea-deployment
labels:
app: gitea
spec:
replicas: 1
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
containers:
- name: gitea
image: gitea/gitea:latest
ports:
- containerPort: 3000
name: gitea
- containerPort: 22
name: git-ssh
volumeMounts:
- mountPath: /data
name: git-data
volumes:
- name: git-data
hostPath:
path: /mnt/kube-data/gitea
type: Directory
nodeSelector:
git-data-storage: "true"

that uses our git-data-storage tag in the nodeSelector and when I create the volume:

volumeMounts:
- mountPath: /data
name: git-data
volumes:
- name: git-data
hostPath:
path: /mnt/kube-data/gitea
type: Directory

The path on the host /mnt/kube-data/gitea is mounted where the container expects on the gitea image, /data . You can load data into the volume through the host (or, in my case, since this is a block device that was mounted to my standlone git server, I mounted it with the data tree already present and ready to be imported), and start the Deployment.

In order to expose the web UI and the SSH port (for your git client, if you use git+ssh as your main transport method), you can setup a service to forward the ports we exposed in our deployment, 22 and 3000:

kind: Service
apiVersion: v1
metadata:
name: gitea-service
spec:
selector:
app: gitea
ports:
- name: gitea-http
port: 3000
targetPort: gitea-http
- name: gitea-ssh
port: 2222
targetPort: gitea-ssh

and then you can use type:LoadBalancer to expose this outside of the cluster network, if you’d like.