The last component to setup in its own Kustomize project is the Gitea server itself.
Gitea is a platform specialized in storing and handling Git repositories, which you can upload to Gitea through HTTP or SSH connections. Moreover, Gitea comes with a web console and embedded Prometheus-formatted metrics. All of this means that you'll run one Gitea container but with two ports opened on it.
Prepare your Gitea's Kustomize project folder tree as follows.
$ mkdir -p $HOME/k8sprjs/gitea/components/server-gitea/{configs,resources}Notice that there's no secret folder to be created this time.
Here I'll tell you about preparing just one properties file with a couple of values. The Gitea server's configuration will be done by declaring special environment variables.
You'll want to keep certain parameters in a params.properties file for convenience.
-
Create the file
params.propertiesunder theconfigspath.$ touch $HOME/k8sprjs/gitea/components/server-gitea/configs/params.properties -
Set the parameters below in
params.properties.cache-redis-svc-fqdn=gitea-cache-redis.gitea.svc.deimos.cluster.io db-postgresql-svc-fqdn=gitea-db-postgresql.gitea.svc.deimos.cluster.io
The parameters set above mean the following.
cache-redis-svc-fqdn: the internal FQDN of the Redis service for Gitea.db-postgresql-svc-fqdn: the internal FQDN of the PostgreSQL service for Gitea.
You'll require two persistent volumes for your Gitea server.
- One PV for storing the server's data files.
- One PV to store users' Git repositories.
So you also need declaring two different claim resources, one per PV.
-
Create a file named
data-server-gitea.persistentvolumeclaim.yamlunderresources.$ touch $HOME/k8sprjs/gitea/components/server-gitea/resources/data-server-gitea.persistentvolumeclaim.yaml -
Copy the yaml below in
data-server-gitea.persistentvolumeclaim.yaml.apiVersion: v1 kind: PersistentVolumeClaim metadata: name: data-server-gitea spec: accessModes: - ReadWriteOnce storageClassName: local-path volumeName: data-gitea resources: requests: storage: 1.2G
-
Create a
repos-server-gitea.persistentvolumeclaim.yamlfile underresources.$ touch $HOME/k8sprjs/gitea/components/server-gitea/resources/repos-server-gitea.persistentvolumeclaim.yaml -
Fill
repos-server-gitea.persistentvolumeclaim.yamlwith the declaration next.apiVersion: v1 kind: PersistentVolumeClaim metadata: name: repos-server-gitea spec: accessModes: - ReadWriteOnce storageClassName: local-path volumeName: repos-gitea resources: requests: storage: 9.3G
Gitea is a server that stores data, so it needs to be deployed with a StatefulSet resource.
-
Create a
server-gitea.statefulset.yamlfile under theresourcespath.$ touch $HOME/k8sprjs/gitea/components/server-gitea/resources/server-gitea.statefulset.yaml -
Put the yaml declaration below in
server-gitea.statefulset.yaml.apiVersion: apps/v1 kind: StatefulSet metadata: name: server-gitea spec: replicas: 1 serviceName: server-gitea template: spec: containers: - name: server image: gitea/gitea:1.15.9 ports: - containerPort: 3000 name: https - containerPort: 22 name: ssh env: - name: GITEA__server__PROTOCOL value: https - name: GITEA__server__DOMAIN value: gitea.deimos.cloud - name: GITEA__server__HTTP_ADDR value: 0.0.0.0 - name: GITEA__server__ROOT_URL value: $(GITEA__server__PROTOCOL)://$(GITEA__server__DOMAIN)/ - name: GITEA__server__CERT_FILE value: https/wildcard.deimos.cloud-tls.crt - name: GITEA__server__KEY_FILE value: https/wildcard.deimos.cloud-tls.key - name: GITEA__repository__ROOT value: /data/gitea/repos - name: GITEA__metrics__ENABLED value: "true" - name: GITEA__database__DB_TYPE value: postgres - name: POSTGRESQL_HOST_FQDN valueFrom: configMapKeyRef: name: server-gitea key: db-postgresql-svc-fqdn - name: GITEA__database__HOST value: "$(POSTGRESQL_HOST_FQDN):5432" - name: GITEA__database__NAME valueFrom: configMapKeyRef: name: db-postgresql key: postgresql-db-name - name: GITEA__database__USER valueFrom: configMapKeyRef: name: db-postgresql key: gitea-username - name: GITEA__database__PASSWD valueFrom: secretKeyRef: name: db-postgresql key: gitea-user-password - name: GITEA__database__SSL_MODE value: disable - name: GITEA__cache__ENABLED value: "true" - name: GITEA__cache__ADAPTER value: redis - name: REDIS_HOST_FQDN valueFrom: configMapKeyRef: name: server-gitea key: cache-redis-svc-fqdn - name: REDIS_HOST_PASSWORD valueFrom: secretKeyRef: name: cache-redis key: redis-password - name: GITEA__cache__HOST value: "redis://:$(REDIS_HOST_PASSWORD)@$(REDIS_HOST_FQDN):6379/0?pool_size=100&idle_timeout=180s" - name: GITEA__queue__TYPE value: redis - name: GITEA__queue__CONN_STR value: "redis://:$(REDIS_HOST_PASSWORD)@$(REDIS_HOST_FQDN):6379/0" - name: GITEA__session__PROVIDER value: redis - name: GITEA__session__PROVIDER_CONFIG value: $(GITEA__cache__HOST) - name: GITEA__session__COOKIE_SECURE value: "true" - name: GITEA__session__COOKIE_NAME value: gitea_cookie - name: GITEA__log__ROUTER_LOG_LEVEL value: trace resources: limits: memory: 256Mi volumeMounts: - name: data-storage mountPath: /data - name: certificate subPath: wildcard.deimos.cloud-tls.crt mountPath: /data/gitea/https/wildcard.deimos.cloud-tls.crt - name: certificate subPath: wildcard.deimos.cloud-tls.key mountPath: /data/gitea/https/wildcard.deimos.cloud-tls.key - name: repos-storage mountPath: /data/gitea/repos volumes: - name: certificate secret: secretName: wildcard.deimos.cloud-tls items: - key: tls.crt path: wildcard.deimos.cloud-tls.crt - key: tls.key path: wildcard.deimos.cloud-tls.key - name: data-storage persistentVolumeClaim: claimName: data-server-gitea - name: repos-storage persistentVolumeClaim: claimName: repos-server-gitea
There are a few particularities in this
StatefulSetin comparison with the others you've seen before.-
servercontainer: there's only one container in the pod. Since Gitea already provides Prometheus metrics, you don't need another sidecar container to run a service that provides those metrics.-
The
imageis for the version1.15.9of Gitea, built on an Alpine Linux system. -
In
portsyou have two ports declared, thehttpsone to access the web interface (Gitea by default listens on the port3000) and thesshfor connecting with this Gitea server through that protocol (which uses the port22as the standard one).BEWARE!
ThecontainerPortdeclarations are essentially informative, they don't actually determine what ports are opened in a pod. That's up to the applications or services running within the pod. Check this thread to know more about this technicality. -
envsection: the main oddity in the variables set here is the format of those namedGITEA_. It's a format explained here that allows the Gitea in this Docker image to overwrite the corresponding configuration parameters in its default/data/gitea/conf/app.inifile with the values set in these variables.GITEA__server__PROTOCOL: indicates on which protocol this Gitea server listens on.GITEA__server__DOMAIN: the domain name for this server. As in other cases, you'll have to enable the domain in your network or directly in your client systems using thehostsfile.GITEA__server__HTTP_ADDR: on which IPs this server will listen on.GITEA__server__ROOT_URL: overwrites the automatically generated public URL. The autogenerated one also includes the port after the domain, which I've removed here because you'll access this Gitea server through the aServiceconfigured to use the standard HTTPS port443.GITEA__server__CERT_FILE: path to the public or crt part of the certificate used for HTTPS communication. The path is relative to the value set in aCUSTOM_PATHvariable which, in the Docker image of Gitea, is set to/data/gitea.GITEA__server__KEY_FILE: path to the private key of the certificate used for HTTPS communications. Also relative to theCUSTOM_PATHvariable.GITEA__repository__ROOT: absolute path to the directory where the Git repositories of the users are kept.GITEA__metrics__ENABLED: for enabling the Prometheus metrics endpoint included in the Gitea server.GITEA__database__DB_TYPE: indicates the type of database Gitea must use.POSTGRESQL_HOST_FQDN: variable for loading as environment variable the FQDN of the PostgreSQL server this Gitea instance will connect to.GITEA__database__HOST: connection string to reach the database for this Gitea instance.GITEA__database__NAME: name of the database to connect to in the database server.GITEA__database__USER: Gitea user's name in the database.GITEA__database__PASSWD: Gitea user's password in the database.GITEA__database__SSL_MODE: for enabling or disabling encryption in the communication with the database.GITEA__cache__ENABLED: for enabling the cache on the Gitea instance.GITEA__cache__ADAPTER: depending on what caching engine you want to use, you'll have to set the proper adapter here to connect to that engine.REDIS_HOST_FQDN: variable for loading as environment variable the FQDN of the Redis server this Gitea instance will connect to.REDIS_HOST_PASSWORD: custom variable to load the password for connecting with the Redis server.GITEA__cache__HOST: the full connection string to reach the cache server.GITEA__queue__TYPE: type of queue to be used.GITEA__queue__CONN_STR: connection string for theredisqueue type.GITEA__session__PROVIDER: indicates what session engine provider you want to use.GITEA__session__PROVIDER_CONFIG: this value will vary depending on what session engine provider you uses. For Redis is the full connection string.GITEA__session__COOKIE_SECURE: whentrue, this forces using HTTPS on all session accesses.GITEA__session__COOKIE_NAME: name of the cookie used for the session ID.
-
volumeMountssection: mounts the certificate files and the two storage volumes for storing Gitea's data.-
/data: the Gitea Docker image will put here contents required to run the instance. -
wildcard.deimos.cloud-tls.crtandwildcard.deimos.cloud-tls.key: the certificate files that, for this Gitea setup, must be placed at/data/gitea/https. -
/data/gitea/repos: folder where Gitea will store the users' Git repositories.BEWARE!
Gitea works with several paths, each with a different purpose. To know more about them, check this FAQ question in the official Gitea documentation. On the other hand, be aware that, in Gitea's Docker image, the path/data/giteais the default one for application data and custom content (like the certificate files).
-
-
-
Now you have to produce the Service for your Gitea setup
-
Create a
server-gitea.service.yamlfile underresources.$ touch $HOME/k8sprjs/gitea/components/server-gitea/resources/server-gitea.service.yaml -
Copy in
server-gitea.service.yamltheServicedeclaration next.apiVersion: v1 kind: Service metadata: annotations: prometheus.io/scrape: "true" prometheus.io/path: /metrics prometheus.io/scheme: "https" prometheus.io/port: "3000" name: server-gitea spec: type: LoadBalancer loadBalancerIP: 192.168.1.43 ports: - port: 443 targetPort: 3000 protocol: TCP name: https - port: 22 protocol: TCP name: ssh
There are a few particularities to notice in this
Servicedeclaration.-
This
Serviceis of theLoadBalancertype, so it gets its external IP from the MetalLB load balancer in your cluster. -
metadata.annotations: up till now you've put here only twoprometheus.ioannotations,scrapeandport. Now here you have two more:path: is the relative URL to the Prometheus metrics endpoint. By default it's expected to be at/metrics, as in this case, but if it's found in another path you'll have to specify it in this annotation.scheme: since the connection to Gitea is secured through HTTPS, you must indicate it by setting this parameter tohttps.
-
On the other hand, it doesn't have any particular internal cluster IP specified. This means that its cluster IP may change on every run so, to reach this service internally, you'll better use its FQDN.
BEWARE!
AServicewith typeLoadBalancercannot have itsclusterIPset asNone. -
The
httpsport redirects the requests reaching the443port to the3000, because that's where the Gitea server is truly listening in its container. -
It has exactly the same
prometheus.ioannotations that were specified in the previousStatefulSet. Notice how theprometheus.io/portannotation has the same number as in thetargetPortof thehttpsport. This seems to be the recommended thing to do, at least according to this article.
-
This Gitea Service resource is under the same particularities as the Redis and PostgreSQL services, so it's FQDN will be a very similar string.
gitea-server-gitea.gitea.svc.deimos.cluster.ioNow you have to put all the Gitea parts together in a kustomization.yaml file.
-
Create a
kustomization.yamlfile in theserver-giteafolder.$ touch $HOME/k8sprjs/gitea/components/server-gitea/kustomization.yaml -
Fill
kustomization.yamlwith the following yaml.# Gitea server setup apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app: server-gitea resources: - resources/data-server-gitea.persistentvolumeclaim.yaml - resources/repos-server-gitea.persistentvolumeclaim.yaml - resources/server-gitea.service.yaml - resources/server-gitea.statefulset.yaml replicas: - name: server-gitea count: 1 images: - name: gitea/gitea newTag: 1.15.9 configMapGenerator: - name: server-gitea envs: - configs/params.properties
The only thing to highlight in this
kustomization.yamlis that there's nosecretGeneratorblock, unlike the cases of the Redis and PostgreSQL components.
As with the other components, you should check the output generated by this Kustomize project.
-
Generate the yaml with
kubectl kustomizeas usual.$ kubectl kustomize $HOME/k8sprjs/gitea/components/server-gitea | less
-
See if your yaml output matches the one below.
apiVersion: v1 data: cache-redis-svc-fqdn: gitea-cache-redis.gitea.svc.deimos.cluster.io db-postgresql-svc-fqdn: gitea-db-postgresql.gitea.svc.deimos.cluster.io kind: ConfigMap metadata: labels: app: server-gitea name: server-gitea-hffkf88tm4 --- apiVersion: v1 kind: Service metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: "3000" prometheus.io/scheme: https prometheus.io/scrape: "true" labels: app: server-gitea name: server-gitea spec: loadBalancerIP: 192.168.1.43 ports: - name: https port: 443 protocol: TCP targetPort: 3000 - name: ssh port: 22 protocol: TCP selector: app: server-gitea type: LoadBalancer --- apiVersion: v1 kind: PersistentVolumeClaim metadata: labels: app: server-gitea name: data-server-gitea spec: accessModes: - ReadWriteOnce resources: requests: storage: 1.2G storageClassName: local-path volumeName: data-gitea --- apiVersion: v1 kind: PersistentVolumeClaim metadata: labels: app: server-gitea name: repos-server-gitea spec: accessModes: - ReadWriteOnce resources: requests: storage: 9.3G storageClassName: local-path volumeName: repos-gitea --- apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: server-gitea name: server-gitea spec: replicas: 1 selector: matchLabels: app: server-gitea serviceName: server-gitea template: metadata: labels: app: server-gitea spec: containers: - env: - name: GITEA__server__PROTOCOL value: https - name: GITEA__server__DOMAIN value: gitea.deimos.cloud - name: GITEA__server__HTTP_ADDR value: 0.0.0.0 - name: GITEA__server__ROOT_URL value: $(GITEA__server__PROTOCOL)://$(GITEA__server__DOMAIN)/ - name: GITEA__server__CERT_FILE value: https/wildcard.deimos.cloud-tls.crt - name: GITEA__server__KEY_FILE value: https/wildcard.deimos.cloud-tls.key - name: GITEA__repository__ROOT value: /data/gitea/repos - name: GITEA__metrics__ENABLED value: "true" - name: GITEA__database__DB_TYPE value: postgres - name: POSTGRESQL_HOST_FQDN valueFrom: configMapKeyRef: key: db-postgresql-svc-fqdn name: server-gitea-hffkf88tm4 - name: GITEA__database__HOST value: $(POSTGRESQL_HOST_FQDN):5432 - name: GITEA__database__NAME valueFrom: configMapKeyRef: key: postgresql-db-name name: db-postgresql - name: GITEA__database__USER valueFrom: configMapKeyRef: key: gitea-username name: db-postgresql - name: GITEA__database__PASSWD valueFrom: secretKeyRef: key: gitea-user-password name: db-postgresql - name: GITEA__database__SSL_MODE value: disable - name: GITEA__cache__ENABLED value: "true" - name: GITEA__cache__ADAPTER value: redis - name: REDIS_HOST_FQDN valueFrom: configMapKeyRef: key: cache-redis-svc-fqdn name: server-gitea-hffkf88tm4 - name: REDIS_HOST_PASSWORD valueFrom: secretKeyRef: key: redis-password name: cache-redis - name: GITEA__cache__HOST value: redis://:$(REDIS_HOST_PASSWORD)@$(REDIS_HOST_FQDN):6379/0?pool_size=100&idle_timeout=180s - name: GITEA__queue__TYPE value: redis - name: GITEA__queue__CONN_STR value: redis://:$(REDIS_HOST_PASSWORD)@$(REDIS_HOST_FQDN):6379/0 - name: GITEA__session__PROVIDER value: redis - name: GITEA__session__PROVIDER_CONFIG value: $(GITEA__cache__HOST) - name: GITEA__session__COOKIE_SECURE value: "true" - name: GITEA__session__COOKIE_NAME value: gitea_cookie - name: GITEA__log__ROUTER_LOG_LEVEL value: trace image: gitea/gitea:1.15.9 name: server ports: - containerPort: 3000 name: https - containerPort: 22 name: ssh resources: limits: memory: 256Mi volumeMounts: - mountPath: /data name: data-storage - mountPath: /data/gitea/https/wildcard.deimos.cloud-tls.crt name: certificate subPath: wildcard.deimos.cloud-tls.crt - mountPath: /data/gitea/https/wildcard.deimos.cloud-tls.key name: certificate subPath: wildcard.deimos.cloud-tls.key - mountPath: /data/gitea/repos name: repos-storage volumes: - name: certificate secret: items: - key: tls.crt path: wildcard.deimos.cloud-tls.crt - key: tls.key path: wildcard.deimos.cloud-tls.key secretName: wildcard.deimos.cloud-tls - name: data-storage persistentVolumeClaim: claimName: data-server-gitea - name: repos-storage persistentVolumeClaim: claimName: repos-server-gitea
This Gitea server cannot be deployed on its own because is missing several elements, like the persistent volumes required by the PVCs and the certificate. As with the Nextcloud platform, you'll tie everything together in this guide's final part.
$HOME/k8sprjs/gitea$HOME/k8sprjs/gitea/components$HOME/k8sprjs/gitea/components/server-gitea$HOME/k8sprjs/gitea/components/server-gitea/configs$HOME/k8sprjs/gitea/components/server-gitea/resources
$HOME/k8sprjs/gitea/components/server-gitea/kustomization.yaml$HOME/k8sprjs/gitea/components/server-gitea/configs/params.properties$HOME/k8sprjs/gitea/components/server-gitea/resources/data-server-gitea.persistentvolumeclaim.yaml$HOME/k8sprjs/gitea/components/server-gitea/resources/repos-server-gitea.persistentvolumeclaim.yaml$HOME/k8sprjs/gitea/components/server-gitea/resources/server-gitea.service.yaml$HOME/k8sprjs/gitea/components/server-gitea/resources/server-gitea.statefulset.yaml
- Why do we need a port/containerPort in a Kubernetes deployment/container definition?
- Kubernetes API. Ports in containers
- Kubernetes & Prometheus Scraping Configuration. Per-pod Prometheus Annotations
- How to Setup Prometheus Monitoring On Kubernetes Cluster
- How to set up auto-discovery of Kubernetes endpoint services in Prometheus
- Gitea Official site
- Gitea Docker image
- Gitea on GitHub
- Installation with Docker
- Configuration Cheat Sheet
- Managing Deployments With Environment Variables
- HTTPS setup to encrypt connections to Gitea
- Gitea
app.example.ini - Gitea Environment To Ini
- Gitea command line global options
- Gitea Configuration Cheat Sheet
- Where does Gitea store what file
- Monitor Gitea with Prometheus
- Install and Configure Gitea Git Service on Kubernetes / OpenShift
- Running Gitea on Kubernetes
- Running Gitea on a Virtual Cloud Server
- Setup a Self-Hosted Git Service with Gitea
- gitea support HA mode for redis & postgres
<< Previous (G034. Deploying services 03. Gitea Part 3) | +Table Of Contents+ | Next (G034. Deploying services 03. Gitea Part 5) >>