This is an automated email from the ASF dual-hosted git repository.

lhotari pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar-helm-chart.git


The following commit(s) were added to refs/heads/master by this push:
     new dc034a8  Initial Dekaf UI support (#637)
dc034a8 is described below

commit dc034a89c26e73b4cf337c0c8dd4b790170dea7e
Author: Kiryl Valkovich <[email protected]>
AuthorDate: Mon Nov 3 13:48:59 2025 +0300

    Initial Dekaf UI support (#637)
---
 .ci/auth/keycloak/values.yaml                      |  12 +++
 .../values.yaml => clusters/values-dekaf.yaml}     |  20 +---
 .github/workflows/pulsar-helm-chart-ci.yaml        |   3 +
 README.md                                          |  24 +++++
 charts/pulsar/templates/_dekaf.tpl                 |  22 ++++
 charts/pulsar/templates/dekaf-deployment.yaml      | 113 +++++++++++++++++++++
 charts/pulsar/templates/dekaf-persistence.yaml     |  47 +++++++++
 .../pulsar/templates/dekaf-service.yaml            |  37 ++++---
 charts/pulsar/values.yaml                          |  53 ++++++++++
 9 files changed, 301 insertions(+), 30 deletions(-)

diff --git a/.ci/auth/keycloak/values.yaml b/.ci/auth/keycloak/values.yaml
index 8334008..a9aaa03 100644
--- a/.ci/auth/keycloak/values.yaml
+++ b/.ci/auth/keycloak/values.yaml
@@ -32,3 +32,15 @@ extraVolumeMounts:
   - name: realm-config
     mountPath: "/opt/bitnami/keycloak/data/import"
     readOnly: true
+
+# Fix for https://github.com/bitnami/charts/issues/35164
+global:
+  security:
+    allowInsecureImages: true
+image:
+  repository: bitnamilegacy/keycloak
+  tag: 26.2.3-debian-12-r0
+postgresql:
+  image:
+    repository: bitnamilegacy/postgresql
+    tag: 17.4.0-debian-12-r17
diff --git a/.ci/auth/keycloak/values.yaml b/.ci/clusters/values-dekaf.yaml
similarity index 64%
copy from .ci/auth/keycloak/values.yaml
copy to .ci/clusters/values-dekaf.yaml
index 8334008..c3c06ec 100644
--- a/.ci/auth/keycloak/values.yaml
+++ b/.ci/clusters/values-dekaf.yaml
@@ -17,18 +17,8 @@
 # under the License.
 #
 
-tls:
-  enabled: false
-# This block sets up an example Pulsar Realm
-# 
https://www.keycloak.org/server/importExport#_importing_a_realm_from_a_directory
-extraEnvVars:
-  - name: KEYCLOAK_EXTRA_ARGS
-    value: "--import-realm"
-extraVolumes:
-  - name: realm-config
-    secret:
-      secretName: keycloak-ci-realm-config
-extraVolumeMounts:
-  - name: realm-config
-    mountPath: "/opt/bitnami/keycloak/data/import"
-    readOnly: true
+components:
+  dekaf: true
+dekaf:
+  persistence:
+    enabled: false
\ No newline at end of file
diff --git a/.github/workflows/pulsar-helm-chart-ci.yaml 
b/.github/workflows/pulsar-helm-chart-ci.yaml
index 6e4b8be..107a69a 100644
--- a/.github/workflows/pulsar-helm-chart-ci.yaml
+++ b/.github/workflows/pulsar-helm-chart-ci.yaml
@@ -224,6 +224,9 @@ jobs:
           - name: ZK & BK TLS Only
             values_file: .ci/clusters/values-zkbk-tls.yaml
             shortname: zkbk-tls
+          - name: Dekaf
+            values_file: .ci/clusters/values-dekaf.yaml
+            shortname: dekaf
           - name: Pulsar Manager
             values_file: .ci/clusters/values-pulsar-manager.yaml
             shortname: pulsar-manager
diff --git a/README.md b/README.md
index b877cfd..3f9e27c 100644
--- a/README.md
+++ b/README.md
@@ -325,8 +325,32 @@ zookeeper:
 
 This is shown in some 
[examples/values-disable-monitoring.yaml](examples/values-disable-monitoring.yaml).
 
+## Dekaf UI
+
+[Dekaf](github.com/visortelle/dekaf) is a new open-source UI for Apache Pulsar.
+
+> :warning: At this moment Dekaf doesn't have built-in authentication. In 
order to prevent unwanted access, it relies on authentication on the Pulsar 
broker side.
+> If your Pulsar instance stores sensitive data, make sure that:
+> - You have configured authentication on the Pulsar side
+> - Dekaf isn't accessible from the Internet
+> - Only authorized persons have access to you Kubernetes namespace
+> Improvements in this area are planned to be implemented later.
+
+To enable the Dekaf component:
+
+- Set the `components.dekaf` property to `true` in the Helm release 
`values.yaml` file.
+- Run the following command to make Dekaf service accessible on your local 
machine.
+
+```
+kubectl port-forward svc/$(kubectl get svc -l component=dekaf -o 
jsonpath='{.items[0].metadata.name}') 8090:8090
+```
+
+- Open <http://localhost:8090> in browser.
+
 ## Pulsar Manager
 
+> :warning: Pulsar Manager has been poorly maintained for a long time. 
Consider the Dekaf UI instead.
+
 The Pulsar Manager can be deployed alongside the pulsar cluster instance.
 Depending on the given settings it uses an existing Secret within the given 
namespace or creates a new one, with random
 passwords for both, the UI and the internal database.
diff --git a/charts/pulsar/templates/_dekaf.tpl 
b/charts/pulsar/templates/_dekaf.tpl
new file mode 100644
index 0000000..7ccf432
--- /dev/null
+++ b/charts/pulsar/templates/_dekaf.tpl
@@ -0,0 +1,22 @@
+{{/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/}}
+
+{{- define "dekaf.component" -}}
+{{ (.Values.dekaf).component | default "dekaf" }}
+{{- end }}
diff --git a/charts/pulsar/templates/dekaf-deployment.yaml 
b/charts/pulsar/templates/dekaf-deployment.yaml
new file mode 100644
index 0000000..67402c7
--- /dev/null
+++ b/charts/pulsar/templates/dekaf-deployment.yaml
@@ -0,0 +1,113 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+{{- if .Values.components.dekaf }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }}
+  namespace: {{ template "pulsar.namespace" . }}
+  labels:
+    {{- include "pulsar.standardLabels" . | nindent 4 }}
+    component: {{ template "dekaf.component" . }}
+  annotations:
+    {{- toYaml (((.Values.dekaf).deployment).annotations | default dict) | 
nindent 4 }}
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      {{- include "pulsar.matchLabels" . | nindent 6 }}
+      component: {{ template "dekaf.component" . }}
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        {{- include "pulsar.template.labels" . | nindent 8 }}
+        component: {{ template "dekaf.component" . }}
+      annotations: {{ ((.Values.dekaf).deployment).podAnnotations | default 
dict | toYaml | nindent 8 }}
+    spec:
+      {{- if ((.Values.dekaf).deployment).nodeSelector }}
+      nodeSelector:
+        {{ toYaml .Values.dekaf.deployment.nodeSelector | default dict | 
indent 10 }}
+      {{- end }}
+
+      {{- if ((.Values.dekaf).deployment).tolerations }}
+      tolerations:
+        {{ toYaml .Values.dekaf.deployment.tolerations | default list | indent 
8 }}
+      {{- end }}
+
+      containers:
+        - name: dekaf
+          image: "{{ .Values.images.dekaf.repository }}:{{ 
.Values.images.dekaf.tag }}"
+          imagePullPolicy: "{{ template "pulsar.imagePullPolicy" (dict "image" 
.Values.images.dekaf "root" .) }}"
+          env:
+          - name: DEKAF_PULSAR_WEB_URL
+            value: "http://{{ template "pulsar.fullname" . }}-{{ 
.Values.broker.component }}:{{ .Values.broker.ports.http }}"
+          - name: DEKAF_PULSAR_BROKER_URL
+            value: "pulsar://{{ template "pulsar.fullname" . }}-{{ 
.Values.broker.component }}:{{ .Values.broker.ports.pulsar }}"
+
+          {{- if ((.Values.dekaf).deployment).extraEnv }}
+            {{- toYaml .Values.dekaf.deployment.extraEnv | default list | 
nindent 10 }}
+          {{- end }}
+
+          ports:
+            - containerPort: 8090
+              name: http
+
+          {{- if ((.Values.dekaf).deployment).resources }}
+          resources:
+            {{- toYaml .Values.dekaf.deployment.resources | nindent 12 }}
+          {{- end }}
+
+          {{- if ((.Values.dekaf).deployment).livenessProbe }}
+          livenessProbe:
+            {{- toYaml .Values.dekaf.deployment.livenessProbe | nindent 12 }}
+          {{- end }}
+
+          {{- if ((.Values.dekaf).deployment).readinessProbe }}
+          readinessProbe:
+            {{- toYaml .Values.dekaf.deployment.readinessProbe | nindent 12 }}
+          {{- end }}
+
+          {{- if ((.Values.dekaf).persistence).enabled }}
+          volumeMounts:
+            - name: {{ template "pulsar.fullname" . }}-{{ template 
"dekaf.component" . }}-library
+              mountPath: /dekaf/data/library
+          {{- end }}
+
+          {{- if ((.Values.dekaf).deployment).extraVolumeMounts }}
+            {{- toYaml .Values.dekaf.deployment.extraVolumeMounts | default 
list | nindent 12 }}
+          {{- end }}
+
+      {{- range ((.Values.dekaf).deployment).extraContainers | default (list) 
}}
+        - {{- toYaml . | nindent 10 }}
+      {{- end }}
+
+      volumes:
+      {{- if ((.Values.dekaf).persistence).enabled }}
+      - name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" 
. }}-library
+        persistentVolumeClaim:
+          claimName: {{ template "pulsar.fullname" . }}-{{ template 
"dekaf.component" . }}-library
+      {{- end }}
+
+      {{- if ((.Values.dekaf).deployment).extraVolumes }}
+        {{- toYaml .Values.dekaf.deployment.extraVolumes | default list | 
nindent 8 }}
+      {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/pulsar/templates/dekaf-persistence.yaml 
b/charts/pulsar/templates/dekaf-persistence.yaml
new file mode 100644
index 0000000..85786df
--- /dev/null
+++ b/charts/pulsar/templates/dekaf-persistence.yaml
@@ -0,0 +1,47 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+{{- if .Values.components.dekaf }}
+{{- if ((.Values.dekaf).persistence).enabled }}
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . 
}}-library
+  namespace: {{ template "pulsar.namespace" . }}
+
+  {{- with ((.Values.dekaf).persistence).annotations }}
+  annotations:
+  {{- toYaml . | nindent 4 }}
+  {{- end }}
+
+  labels:
+    {{- include "pulsar.standardLabels" . | nindent 4 }}
+    {{- if ((.Values.dekaf).persistence).labels }}
+    {{- toYaml .Values.dekaf.persistence.labels | nindent 4 }}
+    {{- end }}
+
+spec:
+  accessModes:
+  {{- (((.Values.dekaf).persistence).accessModes | default (list 
"ReadWriteOnce")) | toYaml | nindent 4 }}
+  resources:
+    requests:
+      storage: "{{ ((.Values.dekaf).persistence).size | default "2Gi" }}"
+  storageClassName: {{ ((.Values.dekaf).persistence).storageClass | default 
nil }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/.ci/auth/keycloak/values.yaml 
b/charts/pulsar/templates/dekaf-service.yaml
similarity index 54%
copy from .ci/auth/keycloak/values.yaml
copy to charts/pulsar/templates/dekaf-service.yaml
index 8334008..7f03c8a 100644
--- a/.ci/auth/keycloak/values.yaml
+++ b/charts/pulsar/templates/dekaf-service.yaml
@@ -17,18 +17,25 @@
 # under the License.
 #
 
-tls:
-  enabled: false
-# This block sets up an example Pulsar Realm
-# 
https://www.keycloak.org/server/importExport#_importing_a_realm_from_a_directory
-extraEnvVars:
-  - name: KEYCLOAK_EXTRA_ARGS
-    value: "--import-realm"
-extraVolumes:
-  - name: realm-config
-    secret:
-      secretName: keycloak-ci-realm-config
-extraVolumeMounts:
-  - name: realm-config
-    mountPath: "/opt/bitnami/keycloak/data/import"
-    readOnly: true
+{{- if .Values.components.dekaf }}
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }}
+  namespace: {{ template "pulsar.namespace" . }}
+  labels:
+    {{- include "pulsar.standardLabels" . | nindent 4 }}
+    component: {{ template "dekaf.component" . }}
+  annotations:
+  {{- if ((.Values.dekaf).service).annotations }}
+    {{ toYaml .Values.dekaf.service.annotations | indent 4 }}
+  {{- end }}
+spec:
+  ports:
+    - name: http
+      port: 8090
+      targetPort: 8090
+  selector:
+    {{- include "pulsar.matchLabels" . | nindent 4 }}
+    component: {{ template "dekaf.component" . }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/pulsar/values.yaml b/charts/pulsar/values.yaml
index 6e6293e..97146ac 100755
--- a/charts/pulsar/values.yaml
+++ b/charts/pulsar/values.yaml
@@ -135,6 +135,8 @@ components:
   toolset: true
   # pulsar manager
   pulsar_manager: false
+  # dekaf UI
+  dekaf: false
 
 # default image repository for pulsar images
 defaultPulsarImageRepository: apachepulsar/pulsar-all
@@ -208,6 +210,11 @@ images:
     # uses defaultPullPolicy when unspecified
     pullPolicy:
     hasCommand: false
+  dekaf:
+    repository: visortelle/dekaf
+    tag: 1.0.0
+    # uses defaultPullPolicy when unspecified
+    pullPolicy:
   oxia:
     repository: oxia/oxia
     tag: 0.14.4
@@ -1807,6 +1814,7 @@ victoria-metrics-k8s-stack:
               caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
               insecureSkipVerify: true  # For development environments like 
minikube
 
+## Pulsar Manager has been poorly maintained for a long time. Consider the 
Dekaf UI instead.
 ## Components Stack: pulsar_manager
 ## templates/pulsar-manager.yaml
 ##
@@ -1911,6 +1919,51 @@ pulsar_manager:
     db_username: "pulsar"
     db_password: ""  # leave empty for random password
 
+# Dekaf is an open-source web-based UI for Apache Pulsar 
https://pulsar.apache.org/docs/next/administration-dekaf-ui/
+dekaf:
+  component: dekaf
+  deployment:
+    annotations: {}
+    podAnnotations: {}
+    nodeSelector: {}
+    tolerations: []
+    extraVolumes: []
+    extraVolumeMounts: []
+    extraContainers: []
+    extraEnv: []
+    resources:
+      requests:
+        memory: "768Mi"
+        cpu: "100m"
+      limits:
+        memory: "4096Mi"
+        cpu: "4000m"
+    livenessProbe:
+      httpGet:
+        path: /health
+        port: http
+        scheme: HTTP
+      periodSeconds: 5
+      initialDelaySeconds: 5
+    readinessProbe:
+      httpGet:
+        path: /health
+        port: http
+        scheme: HTTP
+      periodSeconds: 5
+  service:
+    annotations: {}
+    port: 8090
+  persistence:
+    enabled: true
+    # Storage class must be specified, otherwise you can get an error on Helm 
upgrade
+    storageClass: null
+    size: 2Gi
+    labels: {}
+    annotations: {}
+    accessModes:
+      - ReadWriteOnce
+
 # These are jobs where job ttl configuration is used
 # pulsar-helm-chart/charts/pulsar/templates/pulsar-cluster-initialize.yaml
 # pulsar-helm-chart/charts/pulsar/templates/bookkeeper-cluster-initialize.yaml

Reply via email to