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.properties
under theconfigs
path.$ 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.yaml
underresources
.$ 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.yaml
file underresources
.$ touch $HOME/k8sprjs/gitea/components/server-gitea/resources/repos-server-gitea.persistentvolumeclaim.yaml
-
Fill
repos-server-gitea.persistentvolumeclaim.yaml
with 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.yaml
file under theresources
path.$ 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
StatefulSet
in comparison with the others you've seen before.-
server
container: 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
image
is for the version1.15.9
of Gitea, built on an Alpine Linux system. -
In
ports
you have two ports declared, thehttps
one to access the web interface (Gitea by default listens on the port3000
) and thessh
for connecting with this Gitea server through that protocol (which uses the port22
as the standard one).BEWARE!
ThecontainerPort
declarations 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. -
env
section: 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.ini
file 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 thehosts
file.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 aService
configured 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_PATH
variable 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_PATH
variable.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 theredis
queue 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.
-
volumeMounts
section: 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.crt
andwildcard.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/gitea
is 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.yaml
file underresources
.$ touch $HOME/k8sprjs/gitea/components/server-gitea/resources/server-gitea.service.yaml
-
Copy in
server-gitea.service.yaml
theService
declaration 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
Service
declaration.-
This
Service
is of theLoadBalancer
type, 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.io
annotations,scrape
andport
. 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!
AService
with typeLoadBalancer
cannot have itsclusterIP
set asNone
. -
The
https
port redirects the requests reaching the443
port to the3000
, because that's where the Gitea server is truly listening in its container. -
It has exactly the same
prometheus.io
annotations that were specified in the previousStatefulSet
. Notice how theprometheus.io/port
annotation has the same number as in thetargetPort
of thehttps
port. 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.io
Now you have to put all the Gitea parts together in a kustomization.yaml
file.
-
Create a
kustomization.yaml
file in theserver-gitea
folder.$ touch $HOME/k8sprjs/gitea/components/server-gitea/kustomization.yaml
-
Fill
kustomization.yaml
with 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.yaml
is that there's nosecretGenerator
block, 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 kustomize
as 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) >>