title: “Install via Helm” description: > The steps to install Apache DevLake via Helm for Kubernetes sidebar_position: 2

1 Prerequisites

  • Helm >= 3.6.0
  • Kubernetes >= 1.19.0

2 Quick Start

Check https://github.com/apache/incubator-devlake-helm-chart to contribute!

2.1 Install

To install the chart with release name devlake:

helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart
helm repo update
ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake --version=1.0.0-beta11 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET

Visit your devlake from the node port (32001 by default): http://YOUR-NODE-IP:32001.

Notes for mac users with minikube:

  • forward the port: kubectl port-forward svc/devlake-ui 4000:4000
  • access config-ui: http://YOUR-NODE-IP:4000/
  • access Grafana dashboard: click the dashboard button in config-ui, or visit http://YOUR-NODE-IP:4000/grafana/

2.2 Upgrade

Note:

If you're upgrading from DevLake v0.17.x or earlier versions to v0.18.x or later versions:

  1. Copy the ENCODE_KEY value from /app/config/.env of the lake pod (e.g. devlake-lake-0), and replace the <ENCRYPTION_SECRET> in the upgrade command below.

  2. You may encounter the below error when upgrading because the built-in grafana has been replaced by the official grafana dependency. So you may need to delete the grafana deployment first.

Error: UPGRADE FAILED: cannot patch “devlake-grafana” with kind Deployment: Deployment.apps “devlake-grafana” is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{“app.kubernetes.io/instance”:“devlake”, “app.kubernetes.io/name”:“grafana”}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

helm repo update
helm upgrade devlake devlake/devlake --version=1.0.0-beta11 --set lake.encryptionSecret.secret=<ENCRYPTION_SECRET>

If you're upgrading from DevLake v0.18.x or later versions:

helm repo update
helm upgrade devlake devlake/devlake --version=1.0.0-beta11

2.3 Uninstall

To uninstall/delete the devlake release:

helm uninstall devlake

3 Example Deployments

3.1 Deploy with NodePort

Conditions:

  • IP Address of Kubernetes node: 192.168.0.6
  • Want to visit devlake with port 30000.
ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake --set service.uiPort=30000 --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET

After deployed, visit devlake: http://192.168.0.6:30000

3.2 Deploy with Ingress

Conditions:

ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake --set "ingress.enabled=true,ingress.hostname=devlake.example.com,lake.encryptionSecret.secret=$ENCRYPTION_SECRET"

After deployed, visit devlake: http://devlake.example.com, and grafana at http://devlake.example.com/grafana

3.3 Deploy with Ingress (Https)

Conditions:

  • I have already configured ingress(class: nginx) for the Kubernetes cluster, and the https using 8443 port.
  • I want to use https://devlake-0.example.com:8443 for visiting devlake.
  • The https certificates are generated by letsencrypt.org, and the certificate and key files: cert.pem and key.pem

First, create the secret:

kubectl create secret tls ssl-certificate --cert cert.pem --key secret.pem

Then, deploy the devlake:

ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake \
    --set "ingress.enabled=true,ingress.enableHttps=true,ingress.hostname=devlake-0.example.com" \
    --set "ingress.className=nginx,ingress.httpsPort=8443" \
    --set "ingress.tlsSecretName=ssl-certificate"
    --set "lake.encryptionSecret.secret=$ENCRYPTION_SECRET"

After deployed, visit devlake: https://devlake-0.example.com:8443, and grafana at https://devlake-0.example.com:8443/grafana

3.4 Specify grafana admin password

ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake \
  --set grafana.adminPassword=<your password> \
  --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET

4 Parameters

Some useful parameters for the chart, you could also check them in values.yaml

ParameterDescriptionDefault
replicaCountReplica Count for devlake, currently not used1
imageTagThe version tag for all imagessee Values.yaml
imagePullSecretsName of the Secret for accessing private image registries[]
commonEnvsThe common envs for all pods except grafana{TZ: “UTC”}
mysql.useExternalIf use external mysql server, set truefalse
mysql.externalServerExternal mysql server address127.0.0.1
mysql.externalPortExternal mysql server port3306
mysql.usernameusername for mysqlmerico
mysql.passwordpassword for mysqlmerico
mysql.databasedatabase for mysqllake
mysql.rootPasswordroot password for mysqladmin
mysql.storage.typestorage type, pvc or hostpathpvc
mysql.storage.classstorage class for mysql's volume""
mysql.storage.sizevolume size for mysql's data5Gi
mysql.storage.hostPaththe host path if mysql.storage.type is hostpath/devlake/mysql/data
mysql.image.repositoryrepository for mysql's imagemysql
mysql.image.tagimage tag for mysql's image8
mysql.image.pullPolicypullPolicy for mysql's imageIfNotPresent
mysql.initContainersinit containers to run to complete before mysql[]
mysql.extraLabelsextra labels for mysql's statefulset{}
mysql.securityContextpod security context values{}
mysql.containerSecurityContextcontainer security context values{}
mysql.service.typemysql service typeClusterIP
mysql.service.nodePortspecify mysql nodeport""
grafanadashboard, datasource, etc. settings for grafana, installed by grafana official chart
lake.image.repositoryrepository for lake's imageapache/devlake
lake.image.pullPolicypullPolicy for lake's imageAlways
lake.portthe port of devlake backend8080
lake.envsinitial envs for lakesee Values.yaml
lake.extraEnvsFromSecretexisting secret name of extra envs""
lake.encryptionSecret.secretNamethe k8s secret name for ENCRYPTION_SECRET""
lake.encryptionSecret.secretthe secret for ENCRYPTION_SECRET""
lake.encryptionSecret.autoCreateSecretwhether let the helm chart create the secrettrue
lake.extraLabelsextra labels for lake's deployment template{}
lake.securityContextpod security context values{}
lake.strategypod update strategy{}
lake.containerSecurityContextcontainer security context values{}
lake.livenessProbecontainer livenessprobesee Values.yaml
lake.readinessProbecontainer readinessProbesee Values.yaml
lake.deployment.extraLabelsextra labels for lake's deployment metadata{}
ui.image.repositoryrepository for ui's imageapache/devlake-config-ui
ui.image.pullPolicypullPolicy for ui's imageAlways
ui.basicAuth.enabledIf the basic auth in ui is enabledfalse
ui.basicAuth.userThe user name for the basic auth“admin”
ui.basicAuth.passwordThe password for the basic auth“admin”
ui.basicAuth.autoCreateSecretIf let the helm chart create the secrettrue
ui.basicAuth.secretNameThe basic auth secret name""
ui.extraLabelsextra labels for ui's deployment template{}
ui.securityContextpod security context values{}
ui.strategypod update strategy{}
ui.containerSecurityContextcontainer security context values{}
ui.livenessProbecontainer livenessprobesee Values.yaml
ui.readinessProbecontainer readinessProbesee Values.yaml
ui.deployment.extraLabelsextra labels for ui's deployment metadata{}
service.typeService type for exposed serviceNodePort
service.uiPortNode port for config ui32001
ingress.enabledIf enable ingressfalse
ingress.enableHttpsIf enable httpsfalse
ingress.useDefaultNginxIf use nginx ingress controllertrue
ingress.classNameName for ingressClass. leave empty for using default""
ingress.annotationsThe ingress annotations{}
ingress.hostnameThe hostname/domainname for ingresslocalhost
ingress.prefixThe prefix for endpoints, currently not used/
ingress.tlsSecretNameThe secret name for tls's certificate for https""
ingress.httpPortThe http port for ingress80
ingress.httpsPortThe https port for ingress443
ingress.extraPathsThe extra paths for ingress[]
option.databaseThe database type, valids: mysqlmysql
option.connectionSecretNameThe database connection details secret namedevlake-mysql-auth
option.autoCreateSecretIf let the helm chart create the secrettrue

5 FAQ

  1. Can I use a managed Cloud database service instead of running database in docker?

Yes, it just set useExternal value to true while you deploy devlake with helm chart. Below we'll use MySQL on AWS RDS as an example.

a. (Optional) Create a MySQL instance on AWS RDS following this doc, skip this step if you'd like to use an existing instance b. Proviede below values while install from helm:

- `mysql.useExternal`: this should be `true`
- `mysql.externalServer`: use your RDS instance's IP address or domain name.
- `mysql.externalPort`: use your RDS instance's database port.
- `mysql.username`: use your `username` for access RDS instance's DB
- `mysql.password`: use your `password` for access RDS instance's DB
- `mysql.database`: use your RDS instance's DB name, you may need to create a database first with `CREATE DATABASE <DB name>;`

Here is the example:

helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart
helm repo update
ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake \
  --set mysql.useExternal=true \
  --set mysql.externalServer=db.example.com \
  --set mysql.externalPort=3306 \
  --set mysql.username=admin \
  --set mysql.password=password_4_admin \
  --set mysql.database=devlake
  --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET

  1. Can I use a secret to store the database connection details?

Yes, to do so, you need to have a secret in your Kubernetes Cluster that contains the following values:

  • MYSQL_USER: The user to connect to your DB.
  • MYSQL_PASSWORD: The password to connect to your DB.
  • MYSQL_DATABASE: The database to connect to your DB.
  • MYSQL_ROOT_PASSWORD: The root password to connect to your DB.
  • DB_URL: mysql://username:password@dbserver:port/database?charset=utf8mb4&parseTime=True

The secret name needs to be the same as the value option.connectionSecretName

  1. Can I use an external Grafana instead of running built-in Grafana?

Yes, the devlake helm chart supports using an external Grafana. You can set the following values while installing from helm:

  • grafana.enabled: this should be false
  • grafana.external.url: use your Grafana's URL, e.g. https://grafana.example.com

Here is the example:

helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart
helm repo update
ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake \
  --set grafana.enabled=false \
  --set grafana.external.url=https://grafana.example.com
  --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET

  1. How to set the Grafana admin password? If not explicitly set, a random password will be generated and saved in a Kubernetes Secret
  • grafana.adminPassword: your password

Here is the example:

helm repo add devlake https://apache.github.io/incubator-devlake-helm-chart
helm repo update
ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1)
helm install devlake devlake/devlake \
  --set grafana.adminPassword=<your password> \
  --set lake.encryptionSecret.secret=$ENCRYPTION_SECRET


6 Troubleshooting

If you run into any problem, please check the Troubleshooting or create an issue