Skip to main content

Deploy to Kubernetes Cluster

The commands below install the latest OneDev chart by default. To install a specific OneDev release, add --version <OneDev version> to the helm install command.

Resource Requirement

For an initial OneDev deployment, we suggest starting with a worker node that has 2 CPU cores and 4 GB of memory.

Prerequisite

  1. Kubernetes version 1.19 or later. If you use an ingress controller or cert-manager, also check their supported Kubernetes versions
  2. kubectl and Helm 3 installed
  3. Add the OneDev chart repository:
helm repo add onedev https://code.onedev.io/onedev/~helm
helm repo update onedev

Installation

  1. Install the latest OneDev release:

    helm install onedev onedev/onedev -n onedev --create-namespace

    To install a specific release instead, specify its chart version:

    helm install onedev onedev/onedev --version <OneDev version> -n onedev --create-namespace
  2. Follow instructions on screen to access OneDev

  3. 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 service is exposed via a ClusterIP Service. Below command upgrades an installation to use a LoadBalancer Service:

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

With this command, the cluster's load balancer implementation provisions an external address for the OneDev HTTP service. Managed Kubernetes services normally provide this integration through their cloud controller. Bare-metal and self-managed clusters need a load balancer implementation such as MetalLB; without one, the service's external address remains pending.

Git over SSH requires separate configuration. See Enable Git Access via SSH.

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 via Ingress

Instead of exposing the OneDev Service directly as a LoadBalancer, you can keep it as a ClusterIP Service and route external traffic through an ingress controller. The ingress controller must itself be reachable from outside the cluster, commonly through its own LoadBalancer or NodePort Service, or through host networking. The chart supports nginx and Traefik; select one with ingress.controller.

Set ingress.host to the primary OneDev DNS name. This determines the server URL advertised by OneDev. To route additional DNS names, add them to ingress.additionalHosts. Make sure every configured name resolves to the external IP address of the ingress controller.

Using nginx

Install the ingress-nginx controller if your cluster does not already have it:

helm install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace

Then expose OneDev with a Kubernetes Ingress:

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

The chart applies nginx defaults for sticky sessions and unlimited request body size. Customize them with ingress.nginx.annotations; use ingress.annotations for additional annotations or overrides.

Using Traefik

Install Traefik version 3 if your cluster does not already have it. Both the Kubernetes CRD provider and the Kubernetes Ingress provider are enabled here: the CRD provider serves OneDev's IngressRoute resources, while the Ingress provider is also required if you later use cert-manager's HTTP-01 challenge:

helm install traefik traefik --repo https://traefik.github.io/charts --namespace traefik --create-namespace --set providers.kubernetesCRD.enabled=true --set providers.kubernetesIngress.enabled=true

Then expose OneDev with Traefik IngressRoute resources:

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

Traefik HTTP traffic uses the web entry point by default and switches to websecure when TLS is enabled. Git over SSH is disabled by default and can be enabled separately.

Click here for detailed explanation of ingress settings.

Enable TLS for OneDev HTTP Service

After exposing OneDev via nginx or Traefik, you can enable TLS support with below command:

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

Use Specified TLS Certificate

Until a certificate is configured, the ingress controller may serve its generated default certificate. To use your own key and certificate, create a TLS secret named onedev-tls in the OneDev namespace:

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

The certificate file should contain the server certificate followed by any required intermediate certificates. If the certificate is self-signed or issued by a private certificate authority, clients need to trust that certificate or authority explicitly.

Getting TLS Certificate Automatically

Alternatively, you can configure OneDev to populate the onedev-tls secret automatically by obtaining a certificate from an ACME provider (currently only Let's Encrypt is supported). First, install cert-manager if it is not already installed:

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 the command below to enable TLS with ACME:

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 HTTP-01 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

Enable Git Access via SSH

Git access via SSH is disabled by default. Enable the SSH port with below command:

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

By default, the SSH port is added to OneDev's main Service. Set ssh.separateService.enabled=true when SSH needs an independent Service with its own type, IP address, annotations, or traffic policy.

If OneDev is exposed via a LoadBalancer Service, no further Kubernetes configuration is necessary unless using a separate SSH Service. In that case, also set ssh.separateService.type=LoadBalancer.

Using nginx ingress

Kubernetes Ingress only routes HTTP traffic. After enabling SSH above, configure the nginx controller to forward port 22 to OneDev:

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

When using a separate SSH Service, replace onedev/onedev:ssh with onedev/onedev-ssh:ssh.

Using Traefik ingress

When SSH is enabled, the chart creates an IngressRouteTCP using a Traefik entry point named gitssh. Declare this entry point in the Traefik installation:

ports:
gitssh:
port: 2222
exposedPort: 22
protocol: TCP

No additional OneDev chart setting is necessary. Traefik automatically targets the separate SSH Service when configured.

Finally, update the SSH root URL to ssh://<OneDev DNS name> via menu Administration / System Setting.