Skip to main content

Deploy to Kubernetes Cluster

caution

Procedure outlined here is only applicable for installing latest version

Resource Requirement

Suggest to start with 2 core 4GB work node for initial OneDev deployment

Prerequisite

  1. Kubernetes version 1.18 or Higher
  2. kubectl and helm3 installed
  3. You've added OneDev chart repository with below command:
helm repo add onedev https://code.onedev.io/onedev/~helm
helm repo update onedev

Installation

  1. Install OneDev service
helm install onedev onedev/onedev -n onedev --create-namespace
  1. Follow instructions on screen to access OneDev

  2. You may continue to configure OneDev via helm values

Use External Database

By default, OneDev uses an internal database, and it is suggested to use an external database in production environment. Below command upgrades an installation to use an existing MySQL database (database should be empty initially):

helm upgrade onedev onedev/onedev -n onedev --set database.external=true --set database.type=mysql --set database.host=mysql.example.com --set-string database.port=3306 --set database.name=onedev --set database.user=dbuser --set database.password=dbpassword --reuse-values

Click here for detailed explanations of external database settings

Expose OneDev via Load Balancer

By default OneDev http and ssh services are exposed via ClusterIP service. Below command upgrades an installation to use LoadBalancer service:

helm upgrade onedev onedev/onedev -n onedev --set service.type=LoadBalancer --reuse-values

With this command, you will get an external ip address to access OneDev http and ssh services

Click here for detailed explanations of service related settings

Make sure to update OneDev server url via menu Administration / System Setting to use external ip address or dns name of the load balancer

Expose OneDev Http Service via Ingress

You may expose OneDev service via ingress instead of load balancer with below command:

helm upgrade onedev onedev/onedev -n onedev --set ingress.enabled=true --set ingress.className=<ingress class name> --set ingress.host=<OneDev dns name> --reuse-values

Here:

  1. <ingress class name>: should be replaced with class name of your ingress controller. For instance this value is generally nginx for nginx ingress controller, which can be installed via below command:
helm install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace
  1. <OneDev dns name>: should be replaced with dns name of OneDev. Appropriate dns records need to be added so that this dns name can be resolved to external ip address of corresponding ingress controller

Click here for detailed explanation of ingress related settings

Expose OneDev via Traefik

This is an alternative to exposing http service via ingress above rather than an addition to it, as the chart creates Traefik IngressRoute resources instead of a Kubernetes ingress when Traefik is enabled. You do not need to apply the previous section first, and if you already did, the ingress controller installed there will no longer be used

If your cluster is using Traefik version 3 with its Kubernetes CRD provider enabled, run below command. Unlike a Kubernetes ingress, this routes ssh traffic as well, so http and ssh can be accessed via the same dns name without configuring the controller separately:

helm upgrade onedev onedev/onedev -n onedev --set ingress.enabled=true --set ingress.className=traefik --set ingress.host=<OneDev dns name> --set ingress.traefik.enabled=true --set ingress.traefik.sshEntryPoint=<ssh entry point> --reuse-values

Here:

  1. <OneDev dns name>: should be replaced with dns name of OneDev. This value also determines the server url advertised by OneDev, so it should be set even when routing additional dns names as described below
  2. <ssh entry point>: should be replaced with name of a Traefik entry point forwarding ssh traffic, and defaults to gitssh when not specified. The entry point has to be declared in your Traefik installation, for instance by upgrading Traefik with below values:
ports:
gitssh:
port: 2222
exposedPort: 22
protocol: TCP

Pass an empty value if you do not want ssh to be routed by Traefik at all

Http traffic uses entry point websecure unless ingress.traefik.entryPoint is set to something else. To route more than one dns name to OneDev, list them via ingress.traefik.hosts, keeping ingress.host set to the primary dns name

The chart prints a summary of the entry points and dns names it routes after each install or upgrade, so you can verify ssh is exposed as you expect

After running this command, make sure to update SSH root url at OneDev side as ssh://<OneDev DNS name> in menu Administration/System Setting

Enable TLS for OneDev Http Service

After exposing OneDev http service via ingress or Traefik, you can continue to enable TLS support with below command:

helm upgrade onedev onedev/onedev -n onedev --set ingress.tls.enabled=true --reuse-values

Use Specified TLS Certificate

By default the http service will be using a faked TLS certificate, and you can create a secret onedev-tls to use specified key and certificate like below:

kubectl create secret tls onedev-tls -n onedev --key /path/to/server.key --cert /path/to/server.crt

Getting TLS Certificate Automatically

Alternative, you can configure OneDev to populate secret onedev-tls automatically by getting certificate from ACME providers (currently only supports Let's Encrypt). To do it, first make sure cert manager is installed in your cluster with below command:

helm install cert-manager cert-manager --repo https://charts.jetstack.io --namespace cert-manager --create-namespace --set crds.enabled=true --set global.leaderElection.namespace=cert-manager

Here global.leaderElection.namespace makes cert manager hold its leader election lease in its own namespace instead of kube-system. Managed clusters such as GKE Autopilot deny workloads write access to kube-system, and without this setting cert manager never wins its leader election and stops short of doing any work, including publishing the CA bundle its admission webhook is validated with. Creating the certificate issuer then fails like below:

failed calling webhook "webhook.cert-manager.io": tls: failed to verify certificate: x509: certificate signed by unknown authority

Earlier versions of this document had cert manager installed by applying its release manifest with kubectl. If you did that, uninstall it with kubectl delete -f <manifest url you applied> before running above command

Then run below command to enable tls aceme:

helm upgrade onedev onedev/onedev -n onedev --set ingress.tls.acme.enabled=true --set ingress.tls.acme.email=<your email address> --reuse-values

Here <your email address> should be replaced with your email address to receive certificate notifications such as expiration etc. It has to be a valid address, as Let's Encrypt rejects the account registration otherwise. Note that ingress.tls.enabled also needs to be true for the certificate issuer to be created.

caution

Cert manager solves the http01 challenge through a temporary Kubernetes ingress even when OneDev is exposed via Traefik. If that is the case, make sure ingress.className is set to your Traefik ingress class and that Traefik is installed with its Kubernetes Ingress provider enabled, otherwise the certificate will never be issued

This will get staging certificate which is appropriate for testing purpose. You may run below command to check certificate status:

kubectl describe certificate onedev-tls -n onedev

When you are ready to switch to production certificate, run below command:

helm upgrade onedev onedev/onedev -n onedev --set ingress.tls.acme.production=true --reuse-values

And then delete secret onedev-tls to force cert manager to repopulate it:

kubectl delete secret onedev-tls -n onedev

Wait a while for the certificate to be populated

Expose SSH Service via Ingress Controller

In case OneDev http service is exposed via ingress, you can expose SSH service via same ingress controller via port forwarding so that http and ssh service can be accessed via same dns name. This section applies to a Kubernetes ingress; if OneDev is exposed via Traefik, ssh is already routed by the chart via ingress.traefik.sshEntryPoint and no further configuration is needed here. Taking nginx controller for instance, this can be achieved by upgrading controller like below:

helm upgrade ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx -n ingress-nginx --set tcp.22=onedev/onedev:ssh --reuse-values

After running this command, make sure to update SSH root url at OneDev side as ssh://<OneDev DNS name> in menu Administration/System Setting