├── templates ├── configmap.yaml ├── secret.yaml ├── service.yaml ├── _helpers.tpl └── deployment.yaml ├── Chart.yaml ├── .gitignore ├── values.yaml └── README.md /templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ include "ch-ui.fullname" . }} 5 | labels: 6 | {{- include "ch-ui.labels" . | nindent 4 }} 7 | data: 8 | VITE_CLICKHOUSE_URL: {{ .Values.config.clickhouse.url | quote }} 9 | VITE_CLICKHOUSE_USER: {{ .Values.config.clickhouse.user | quote }} 10 | -------------------------------------------------------------------------------- /templates/secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.config.clickhouse.password (not .Values.config.clickhouse.existingSecret) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "ch-ui.fullname" . }} 6 | labels: 7 | {{- include "ch-ui.labels" . | nindent 4 }} 8 | type: Opaque 9 | data: 10 | clickhouse-password: {{ .Values.config.clickhouse.password | b64enc | quote }} 11 | {{- end }} -------------------------------------------------------------------------------- /Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: ch-ui 3 | description: A Helm chart for CH-UI - ClickHouse Web UI 4 | type: application 5 | version: 0.1.0 6 | appVersion: "latest" 7 | keywords: 8 | - clickhouse 9 | - database 10 | - ui 11 | - management 12 | home: https://github.com/caioricciuti/ch-ui 13 | sources: 14 | - https://github.com/caioricciuti/ch-ui 15 | maintainers: 16 | - name: ch-ui 17 | url: https://github.com/caioricciuti/ch-ui -------------------------------------------------------------------------------- /templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "ch-ui.fullname" . }} 5 | labels: 6 | {{- include "ch-ui.labels" . | nindent 4 }} 7 | {{- with .Values.service.annotations }} 8 | annotations: 9 | {{- toYaml . | nindent 4 }} 10 | {{- end }} 11 | spec: 12 | type: {{ .Values.service.type }} 13 | ports: 14 | - port: {{ .Values.service.port }} 15 | targetPort: http 16 | protocol: TCP 17 | name: http 18 | selector: 19 | {{- include "ch-ui.selectorLabels" . | nindent 4 }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/vim,osx,helm 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=vim,osx,helm 4 | 5 | ### Helm ### 6 | # Chart dependencies 7 | **/charts/*.tgz 8 | 9 | ### OSX ### 10 | # General 11 | .DS_Store 12 | .AppleDouble 13 | .LSOverride 14 | 15 | # Icon must end with two \r 16 | Icon 17 | 18 | 19 | # Thumbnails 20 | ._* 21 | 22 | # Files that might appear in the root of a volume 23 | .DocumentRevisions-V100 24 | .fseventsd 25 | .Spotlight-V100 26 | .TemporaryItems 27 | .Trashes 28 | .VolumeIcon.icns 29 | .com.apple.timemachine.donotpresent 30 | 31 | # Directories potentially created on remote AFP share 32 | .AppleDB 33 | .AppleDesktop 34 | Network Trash Folder 35 | Temporary Items 36 | .apdisk 37 | 38 | ### Vim ### 39 | # Swap 40 | [._]*.s[a-v][a-z] 41 | !*.svg # comment out if you don't need vector files 42 | [._]*.sw[a-p] 43 | [._]s[a-rt-v][a-z] 44 | [._]ss[a-gi-z] 45 | [._]sw[a-p] 46 | 47 | # Session 48 | Session.vim 49 | Sessionx.vim 50 | 51 | # Temporary 52 | .netrwhist 53 | *~ 54 | # Auto-generated tag files 55 | tags 56 | # Persistent undo 57 | [._]*.un~ 58 | 59 | # End of https://www.toptal.com/developers/gitignore/api/vim,osx,helm 60 | -------------------------------------------------------------------------------- /templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "ch-ui.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "ch-ui.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "ch-ui.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "ch-ui.labels" -}} 37 | helm.sh/chart: {{ include "ch-ui.chart" . }} 38 | {{ include "ch-ui.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "ch-ui.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "ch-ui.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "ch-ui.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "ch-ui.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} -------------------------------------------------------------------------------- /values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | 3 | image: 4 | repository: ghcr.io/caioricciuti/ch-ui 5 | pullPolicy: IfNotPresent 6 | tag: "latest" 7 | 8 | imagePullSecrets: [] 9 | nameOverride: "" 10 | fullnameOverride: "" 11 | 12 | serviceAccount: 13 | create: true 14 | annotations: {} 15 | name: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | 21 | securityContext: {} 22 | 23 | service: 24 | type: ClusterIP 25 | port: 80 26 | targetPort: 5521 27 | annotations: {} 28 | 29 | ingress: 30 | enabled: false 31 | className: "" 32 | annotations: {} 33 | hosts: 34 | - host: ch-ui.local 35 | paths: 36 | - path: / 37 | pathType: ImplementationSpecific 38 | tls: [] 39 | 40 | resources: 41 | limits: 42 | cpu: 500m 43 | memory: 512Mi 44 | requests: 45 | cpu: 250m 46 | memory: 256Mi 47 | 48 | autoscaling: 49 | enabled: false 50 | minReplicas: 1 51 | maxReplicas: 10 52 | targetCPUUtilizationPercentage: 80 53 | targetMemoryUtilizationPercentage: 80 54 | 55 | nodeSelector: {} 56 | 57 | tolerations: [] 58 | 59 | affinity: {} 60 | 61 | config: 62 | clickhouse: 63 | # Option 1: Provide values directly 64 | url: "http://clickhouse:8123" 65 | user: "default" 66 | password: "" 67 | useAdvanced: false 68 | # Option 2: Use an existing secret 69 | # If existingSecret is set, it will override the above values 70 | existingSecret: "" 71 | # Keys in the existing secret (defaults shown) 72 | existingSecretKeys: 73 | password: "VITE_CLICKHOUSE_PASS" 74 | app: 75 | basePath: "" 76 | requestTimeout: 30000 77 | distributed: false 78 | 79 | env: [] 80 | 81 | envFrom: [] 82 | 83 | livenessProbe: 84 | httpGet: 85 | path: / 86 | port: http 87 | initialDelaySeconds: 30 88 | periodSeconds: 10 89 | timeoutSeconds: 5 90 | failureThreshold: 3 91 | 92 | readinessProbe: 93 | httpGet: 94 | path: / 95 | port: http 96 | initialDelaySeconds: 5 97 | periodSeconds: 10 98 | timeoutSeconds: 5 99 | failureThreshold: 3 100 | -------------------------------------------------------------------------------- /templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "ch-ui.fullname" . }} 5 | labels: 6 | {{- include "ch-ui.labels" . | nindent 4 }} 7 | spec: 8 | {{- if not .Values.autoscaling.enabled }} 9 | replicas: {{ .Values.replicaCount }} 10 | {{- end }} 11 | selector: 12 | matchLabels: 13 | {{- include "ch-ui.selectorLabels" . | nindent 6 }} 14 | template: 15 | metadata: 16 | annotations: 17 | checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} 18 | {{- with .Values.podAnnotations }} 19 | {{- toYaml . | nindent 8 }} 20 | {{- end }} 21 | labels: 22 | {{- include "ch-ui.selectorLabels" . | nindent 8 }} 23 | spec: 24 | {{- with .Values.imagePullSecrets }} 25 | imagePullSecrets: 26 | {{- toYaml . | nindent 8 }} 27 | {{- end }} 28 | serviceAccountName: {{ include "ch-ui.serviceAccountName" . }} 29 | securityContext: 30 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 31 | containers: 32 | - name: {{ .Chart.Name }} 33 | securityContext: 34 | {{- toYaml .Values.securityContext | nindent 12 }} 35 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 36 | imagePullPolicy: {{ .Values.image.pullPolicy }} 37 | ports: 38 | - name: http 39 | containerPort: 5521 40 | protocol: TCP 41 | envFrom: 42 | - configMapRef: 43 | name: {{ include "ch-ui.fullname" . }} 44 | {{- with .Values.envFrom }} 45 | {{- toYaml . | nindent 12 }} 46 | {{- end }} 47 | env: 48 | {{- if .Values.config.clickhouse.existingSecret }} 49 | # When using existing secret, map all ClickHouse config from it 50 | - name: VITE_CLICKHOUSE_PASS 51 | valueFrom: 52 | secretKeyRef: 53 | name: {{ .Values.config.clickhouse.existingSecret }} 54 | key: {{ .Values.config.clickhouse.existingSecretKeys.password }} 55 | {{- else if .Values.config.clickhouse.password }} 56 | # When using inline password (not recommended for production) 57 | - name: VITE_CLICKHOUSE_PASS 58 | valueFrom: 59 | secretKeyRef: 60 | name: {{ include "ch-ui.fullname" . }} 61 | key: clickhouse-password 62 | {{- end }} 63 | {{- if .Values.config.clickhouse.useAdvanced }} 64 | - name: VITE_CLICKHOUSE_USE_ADVANCED 65 | value: "true" 66 | {{- end }} 67 | {{- if .Values.config.app.basePath }} 68 | - name: VITE_BASE_PATH 69 | value: {{ .Values.config.app.basePath | quote }} 70 | {{- end }} 71 | {{- if .Values.config.app.requestTimeout }} 72 | - name: VITE_REQUEST_TIMEOUT 73 | value: {{ .Values.config.app.requestTimeout | quote }} 74 | {{- end }} 75 | {{- if .Values.config.app.distributed }} 76 | - name: VITE_DISTRIBUTED 77 | value: "true" 78 | {{- end }} 79 | {{- with .Values.env }} 80 | {{- toYaml . | nindent 12 }} 81 | {{- end }} 82 | livenessProbe: 83 | {{- toYaml .Values.livenessProbe | nindent 12 }} 84 | readinessProbe: 85 | {{- toYaml .Values.readinessProbe | nindent 12 }} 86 | resources: 87 | {{- toYaml .Values.resources | nindent 12 }} 88 | {{- with .Values.nodeSelector }} 89 | nodeSelector: 90 | {{- toYaml . | nindent 8 }} 91 | {{- end }} 92 | {{- with .Values.affinity }} 93 | affinity: 94 | {{- toYaml . | nindent 8 }} 95 | {{- end }} 96 | {{- with .Values.tolerations }} 97 | tolerations: 98 | {{- toYaml . | nindent 8 }} 99 | {{- end }} 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CH-UI Helm Chart 2 | 3 | This Helm chart deploys [CH-UI](https://github.com/caioricciuti/ch-ui), a web interface for ClickHouse database management. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | helm install ch-ui ./ch-ui-helm 9 | ``` 10 | 11 | ## Configuration Options 12 | 13 | The chart supports two methods for configuring ClickHouse connection: 14 | 15 | ### Method 1: Direct Configuration (Default) 16 | 17 | Provide ClickHouse connection details directly in values: 18 | 19 | ```yaml 20 | config: 21 | clickhouse: 22 | url: "http://clickhouse:8123" 23 | user: "default" 24 | password: "mypassword" 25 | ``` 26 | 27 | Or via command line: 28 | 29 | ```bash 30 | helm install ch-ui ./ch-ui-helm \ 31 | --set config.clickhouse.url=http://my-clickhouse:8123 \ 32 | --set config.clickhouse.user=myuser \ 33 | --set config.clickhouse.password=mypassword 34 | ``` 35 | 36 | ### Method 2: Using Existing Secret (Recommended for Production) 37 | 38 | Reference an existing Kubernetes secret containing ClickHouse credentials: 39 | 40 | 1. First, create a secret with your ClickHouse credentials: 41 | 42 | ```bash 43 | kubectl create secret generic clickhouse-secret \ 44 | --from-literal=VITE_CLICKHOUSE_URL=http://clickhouse:8123 \ 45 | --from-literal=VITE_CLICKHOUSE_USER=myuser \ 46 | --from-literal=VITE_CLICKHOUSE_PASS=mypassword 47 | ``` 48 | 49 | 2. Then reference it in your values: 50 | 51 | ```yaml 52 | config: 53 | clickhouse: 54 | existingSecret: "clickhouse-secret" 55 | existingSecretKeys: 56 | url: "VITE_CLICKHOUSE_URL" 57 | user: "VITE_CLICKHOUSE_USER" 58 | password: "VITE_CLICKHOUSE_PASS" 59 | ``` 60 | 61 | Or via command line: 62 | 63 | ```bash 64 | helm install ch-ui ./ch-ui-helm \ 65 | --set config.clickhouse.existingSecret=clickhouse-secret 66 | ``` 67 | 68 | If your secret uses different keys, you can customize them: 69 | 70 | ```yaml 71 | config: 72 | clickhouse: 73 | existingSecret: "my-custom-secret" 74 | existingSecretKeys: 75 | url: "clickhouse-host" 76 | user: "clickhouse-username" 77 | password: "clickhouse-password" 78 | ``` 79 | 80 | ## Key Configuration Parameters 81 | 82 | | Parameter | Description | Default | 83 | |-----------|-------------|---------| 84 | | `replicaCount` | Number of replicas | `1` | 85 | | `image.repository` | Image repository | `ghcr.io/caioricciuti/ch-ui` | 86 | | `image.tag` | Image tag | `latest` | 87 | | `service.type` | Service type | `ClusterIP` | 88 | | `service.port` | Service port | `80` | 89 | | `config.clickhouse.url` | ClickHouse URL (when not using existingSecret) | `http://clickhouse:8123` | 90 | | `config.clickhouse.user` | ClickHouse user (when not using existingSecret) | `default` | 91 | | `config.clickhouse.password` | ClickHouse password (when not using existingSecret) | `""` | 92 | | `config.clickhouse.existingSecret` | Name of existing secret with ClickHouse credentials | `""` | 93 | | `config.clickhouse.existingSecretKeys.*` | Keys in the existing secret | See values.yaml | 94 | | `config.app.basePath` | Base path for reverse proxy | `""` | 95 | | `config.app.requestTimeout` | Request timeout in milliseconds | `30000` | 96 | | `config.app.distributed` | Enable distributed mode for clusters | `false` | 97 | | `ingress.enabled` | Enable ingress | `false` | 98 | | `resources.limits` | Resource limits | `{cpu: 500m, memory: 512Mi}` | 99 | | `resources.requests` | Resource requests | `{cpu: 250m, memory: 256Mi}` | 100 | 101 | ## Examples 102 | 103 | ### Basic Installation with Inline Credentials 104 | 105 | ```bash 106 | helm install ch-ui ./ch-ui-helm \ 107 | --set config.clickhouse.url=http://clickhouse:8123 \ 108 | --set config.clickhouse.user=admin \ 109 | --set config.clickhouse.password=secret123 110 | ``` 111 | 112 | ### Production Installation with External Secret 113 | 114 | ```bash 115 | # Create secret 116 | kubectl create secret generic prod-clickhouse \ 117 | --from-literal=VITE_CLICKHOUSE_URL=https://clickhouse.prod:8443 \ 118 | --from-literal=VITE_CLICKHOUSE_USER=prod-user \ 119 | --from-literal=VITE_CLICKHOUSE_PASS=prod-password 120 | 121 | # Install chart 122 | helm install ch-ui ./ch-ui-helm \ 123 | --set config.clickhouse.existingSecret=prod-clickhouse \ 124 | --set ingress.enabled=true \ 125 | --set ingress.hosts[0].host=ch-ui.example.com 126 | ``` 127 | 128 | ### Installation with Custom Resources and Replicas 129 | 130 | ```bash 131 | helm install ch-ui ./ch-ui-helm \ 132 | --set replicaCount=3 \ 133 | --set resources.limits.cpu=1000m \ 134 | --set resources.limits.memory=1Gi \ 135 | --set config.clickhouse.existingSecret=clickhouse-creds 136 | ``` 137 | 138 | ## Uninstallation 139 | 140 | ```bash 141 | helm uninstall ch-ui 142 | ``` --------------------------------------------------------------------------------