update
diff --git a/charts/jenkins/templates/jenkins-controller-statefulset.yaml b/charts/jenkins/templates/jenkins-controller-statefulset.yaml
new file mode 100644
index 0000000..ca0edc6
--- /dev/null
+++ b/charts/jenkins/templates/jenkins-controller-statefulset.yaml
@@ -0,0 +1,413 @@
+{{- if .Capabilities.APIVersions.Has "apps/v1" }}
+apiVersion: apps/v1
+{{- else }}
+apiVersion: apps/v1beta1
+{{- end }}
+kind: StatefulSet
+metadata:
+  name: {{ template "jenkins.fullname" . }}
+  namespace: {{ template "jenkins.namespace" . }}
+  labels:
+    "app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
+    {{- if .Values.renderHelmLabels }}
+    "helm.sh/chart": "{{ template "jenkins.label" .}}"
+    {{- end }}
+    "app.kubernetes.io/managed-by": "{{ .Release.Service }}"
+    "app.kubernetes.io/instance": "{{ .Release.Name }}"
+    "app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
+    {{- range $key, $val := .Values.controller.statefulSetLabels }}
+    {{ $key }}: {{ $val | quote }}
+    {{- end}}
+  {{- if .Values.controller.statefulSetAnnotations }}
+  annotations:
+{{ toYaml .Values.controller.statefulSetAnnotations | indent 4 }}
+  {{- end }}
+spec:
+  serviceName: {{ template "jenkins.fullname" . }}
+  replicas: 1
+  selector:
+    matchLabels:
+      "app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
+      "app.kubernetes.io/instance": "{{ .Release.Name }}"
+  {{- if .Values.controller.updateStrategy }}
+  updateStrategy:
+{{ toYaml .Values.controller.updateStrategy | indent 4 }}
+  {{- end }}
+  template:
+    metadata:
+      labels:
+        "app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
+        "app.kubernetes.io/managed-by": "{{ .Release.Service }}"
+        "app.kubernetes.io/instance": "{{ .Release.Name }}"
+        "app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
+        {{- range $key, $val := .Values.controller.podLabels }}
+        {{ $key }}: {{ $val | quote }}
+        {{- end}}
+      annotations:
+        checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
+        {{- if .Values.controller.initScripts }}
+        checksum/config-init-scripts: {{ include (print $.Template.BasePath "/config-init-scripts.yaml") . | sha256sum }}
+        {{- end }}
+        {{- if .Values.controller.podAnnotations }}
+{{ tpl (toYaml .Values.controller.podAnnotations | indent 8) . }}
+        {{- end }}
+    spec:
+      {{- if .Values.controller.schedulerName }}
+      schedulerName: {{ .Values.controller.schedulerName }}
+      {{- end }}
+      {{- if .Values.controller.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.controller.nodeSelector | indent 8 }}
+      {{- end }}
+      {{- if .Values.controller.tolerations }}
+      tolerations:
+{{ toYaml .Values.controller.tolerations | indent 8 }}
+      {{- end }}
+      {{- if .Values.controller.affinity }}
+      affinity:
+{{ toYaml .Values.controller.affinity | indent 8 }}
+      {{- end }}
+      {{- if quote .Values.controller.terminationGracePeriodSeconds }}
+      terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
+      {{- end }}
+      {{- if .Values.controller.priorityClassName }}
+      priorityClassName: {{ .Values.controller.priorityClassName }}
+      {{- end }}
+      {{- if .Values.controller.shareProcessNamespace }}
+      shareProcessNamespace: true
+      {{- end }}
+{{- if .Values.controller.usePodSecurityContext }}
+      securityContext:
+  {{- if kindIs "map" .Values.controller.podSecurityContextOverride }}
+    {{- tpl (toYaml .Values.controller.podSecurityContextOverride | nindent 8) . -}}
+  {{- else }}
+    {{/* The rest of this section should be replaced with the contents of this comment one the runAsUser, fsGroup, and securityContextCapabilities Helm chart values have been removed:
+        runAsUser: 1000
+        fsGroup: 1000
+        runAsNonRoot: true
+    */}}
+        runAsUser: {{ default 0 .Values.controller.runAsUser }}
+    {{- if and (.Values.controller.runAsUser) (.Values.controller.fsGroup) }}
+      {{- if not (eq (int .Values.controller.runAsUser) 0) }}
+        fsGroup: {{ .Values.controller.fsGroup }}
+        runAsNonRoot: true
+      {{- end }}
+      {{- if .Values.controller.securityContextCapabilities }}
+        capabilities:
+          {{- toYaml .Values.controller.securityContextCapabilities | nindent 10 }}
+      {{- end }}
+    {{- end }}
+  {{- end }}
+{{- end }}
+      serviceAccountName: "{{ template "jenkins.serviceAccountName" . }}"
+{{- if .Values.controller.hostNetworking }}
+      hostNetwork: true
+      dnsPolicy: ClusterFirstWithHostNet
+{{- end }}
+      {{- if .Values.controller.hostAliases }}
+      hostAliases:
+        {{- toYaml .Values.controller.hostAliases | nindent 8 }}
+      {{- end }}
+      initContainers:
+{{- if .Values.controller.customInitContainers }}
+{{ tpl (toYaml .Values.controller.customInitContainers) . | indent 8 }}
+{{- end }}
+
+{{- if .Values.controller.sidecars.configAutoReload.enabled }}
+{{- include "jenkins.configReloadContainer" (list $ "config-reload-init" "init") | nindent 8 }}
+{{- end}}
+
+        - name: "init"
+          image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}"
+          imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}"
+          {{- if .Values.controller.containerSecurityContext }}
+          securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }}
+          {{- end }}
+          command: [ "sh", "/var/jenkins_config/apply_config.sh" ]
+            {{- if .Values.controller.initContainerEnvFrom }}
+          envFrom:
+{{ (tpl (toYaml .Values.controller.initContainerEnvFrom) .) | indent 12 }}
+            {{- end }}
+            {{- if .Values.controller.initContainerEnv }}
+          env:
+{{ (tpl (toYaml .Values.controller.initContainerEnv) .) | indent 12 }}
+            {{- end }}
+          resources:
+{{- if .Values.controller.initContainerResources }}
+{{ toYaml .Values.controller.initContainerResources | indent 12 }}
+{{- else }}
+{{ toYaml .Values.controller.resources | indent 12 }}
+{{- end }}
+          volumeMounts:
+            {{- if .Values.persistence.mounts }}
+{{ toYaml .Values.persistence.mounts | indent 12 }}
+            {{- end }}
+            - mountPath: {{ .Values.controller.jenkinsHome }}
+              name: jenkins-home
+              {{- if .Values.persistence.subPath }}
+              subPath: {{ .Values.persistence.subPath }}
+              {{- end }}
+            - mountPath: /var/jenkins_config
+              name: jenkins-config
+            {{- if .Values.controller.installPlugins }}
+            {{- if .Values.controller.overwritePluginsFromImage }}
+            - mountPath: {{ .Values.controller.jenkinsRef }}/plugins
+              name: plugins
+            {{- end }}
+            - mountPath: /var/jenkins_plugins
+              name: plugin-dir
+            - mountPath: /tmp
+              name: tmp-volume
+            {{- end }}
+            {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }}
+            - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d
+              name: init-scripts
+            {{- end }}
+            {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
+            {{- $httpsJKSDirPath :=  printf "%s" .Values.controller.httpsKeyStore.path }}
+            - mountPath: {{ $httpsJKSDirPath }}
+              name: jenkins-https-keystore
+            {{- end }}
+      containers:
+        - name: jenkins
+          image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}"
+          imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}"
+          {{- if .Values.controller.containerSecurityContext }}
+          securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }}
+          {{- end }}
+          {{- if .Values.controller.overrideArgs }}
+          args: [
+            {{- range $overrideArg := .Values.controller.overrideArgs }}
+              "{{- tpl $overrideArg $ }}",
+            {{- end }}
+          ]
+          {{- else if .Values.controller.httpsKeyStore.enable }}
+          {{- $httpsJKSFilePath :=  printf "%s/%s" .Values.controller.httpsKeyStore.path .Values.controller.httpsKeyStore.fileName }}
+          args: [ "--httpPort={{.Values.controller.httpsKeyStore.httpPort}}", "--httpsPort={{.Values.controller.targetPort}}", '--httpsKeyStore={{ $httpsJKSFilePath }}', "--httpsKeyStorePassword=$(JENKINS_HTTPS_KEYSTORE_PASSWORD)" ]
+          {{- else }}
+          args: [ "--httpPort={{.Values.controller.targetPort}}"]
+          {{- end }}
+          {{- if .Values.controller.lifecycle }}
+          lifecycle:
+{{ toYaml .Values.controller.lifecycle | indent 12 }}
+          {{- end }}
+{{- if .Values.controller.terminationMessagePath }}
+          terminationMessagePath: {{ .Values.controller.terminationMessagePath }}
+{{- end }}
+{{- if .Values.controller.terminationMessagePolicy }}
+          terminationMessagePolicy: {{ .Values.controller.terminationMessagePolicy }}
+{{- end }}
+            {{- if .Values.controller.containerEnvFrom }}
+          envFrom:
+{{ (tpl ( toYaml .Values.controller.containerEnvFrom) .) | indent 12 }}
+            {{- end }}
+          env:
+            {{- if .Values.controller.containerEnv }}
+{{ (tpl ( toYaml .Values.controller.containerEnv) .) | indent 12 }}
+            {{- end }}
+            {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
+            - name: SECRETS
+              value: /run/secrets/additional
+            {{- end }}
+            - name: POD_NAME
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.name
+            - name: JAVA_OPTS
+              value: >-
+                {{ if .Values.controller.sidecars.configAutoReload.enabled }} -Dcasc.reload.token=$(POD_NAME) {{ end }}{{ default "" .Values.controller.javaOpts }}
+            - name: JENKINS_OPTS
+              value: >-
+                {{ if .Values.controller.jenkinsUriPrefix }}--prefix={{ .Values.controller.jenkinsUriPrefix }} {{ end }} --webroot=/var/jenkins_cache/war {{ default "" .Values.controller.jenkinsOpts}}
+            - name: JENKINS_SLAVE_AGENT_PORT
+              value: "{{ .Values.controller.agentListenerPort }}"
+            {{- if .Values.controller.httpsKeyStore.enable }}
+            - name: JENKINS_HTTPS_KEYSTORE_PASSWORD
+            {{- if not .Values.controller.httpsKeyStore.disableSecretMount }}
+              valueFrom:
+                secretKeyRef:
+                  name: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ else if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks  {{ end }}
+                  key: "{{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretKey }}"
+            {{- else }}
+              value: {{ .Values.controller.httpsKeyStore.password }}
+            {{- end }}
+            {{- end }}
+
+            - name: CASC_JENKINS_CONFIG
+              value: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}{{- if .Values.controller.JCasC.configUrls }},{{ join "," .Values.controller.JCasC.configUrls }}{{- end }}
+          ports:
+            {{- if .Values.controller.httpsKeyStore.enable }}
+            - containerPort: {{.Values.controller.httpsKeyStore.httpPort}}
+            {{- else }}
+            - containerPort: {{.Values.controller.targetPort}}
+            {{- end }}
+              name: http
+            - containerPort: {{ .Values.controller.agentListenerPort }}
+              name: agent-listener
+              {{- if .Values.controller.agentListenerHostPort }}
+              hostPort: {{ .Values.controller.agentListenerHostPort }}
+              {{- end }}
+            {{- if .Values.controller.jmxPort }}
+            - containerPort: {{ .Values.controller.jmxPort }}
+              name: jmx
+            {{- end }}
+{{- range $index, $port := .Values.controller.extraPorts }}
+            - containerPort: {{ $port.port }}
+              name: {{ $port.name }}
+{{- end }}
+{{- if and .Values.controller.healthProbes .Values.controller.probes}}
+  {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }}
+          startupProbe:
+{{ tpl (toYaml .Values.controller.probes.startupProbe | indent 12) .}}
+  {{- end }}
+          livenessProbe:
+{{ tpl (toYaml .Values.controller.probes.livenessProbe | indent 12) .}}
+          readinessProbe:
+{{ tpl (toYaml .Values.controller.probes.readinessProbe | indent 12) .}}
+{{- end }}
+          resources:
+{{ toYaml .Values.controller.resources | indent 12 }}
+          volumeMounts:
+{{- if .Values.persistence.mounts }}
+{{ toYaml .Values.persistence.mounts | indent 12 }}
+{{- end }}
+            {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
+            {{- $httpsJKSDirPath :=  printf "%s" .Values.controller.httpsKeyStore.path }}
+            - mountPath: {{ $httpsJKSDirPath }}
+              name: jenkins-https-keystore
+            {{- end }}
+            - mountPath: {{ .Values.controller.jenkinsHome }}
+              name: jenkins-home
+              readOnly: false
+              {{- if .Values.persistence.subPath }}
+              subPath: {{ .Values.persistence.subPath }}
+              {{- end }}
+            - mountPath: /var/jenkins_config
+              name: jenkins-config
+              readOnly: true
+            {{- if .Values.controller.installPlugins }}
+            - mountPath: {{ .Values.controller.jenkinsRef }}/plugins/
+              name: plugin-dir
+              readOnly: false
+            {{- end }}
+            {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }}
+            - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d
+              name: init-scripts
+            {{- end }}
+            {{- if .Values.controller.sidecars.configAutoReload.enabled }}
+            - name: sc-config-volume
+              mountPath: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}
+            {{- end }}
+            {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
+            - name: jenkins-secrets
+              mountPath: /run/secrets/additional
+              readOnly: true
+            {{- end }}
+            - name: jenkins-cache
+              mountPath: /var/jenkins_cache
+            - mountPath: /tmp
+              name: tmp-volume
+
+{{- if .Values.controller.sidecars.configAutoReload.enabled }}
+{{- include "jenkins.configReloadContainer" (list $ "config-reload" "sidecar") | nindent 8 }}
+{{- end}}
+
+
+{{- if .Values.controller.sidecars.additionalSidecarContainers}}
+{{ tpl (toYaml .Values.controller.sidecars.additionalSidecarContainers | indent 8) .}}
+{{- end }}
+
+      volumes:
+{{- if .Values.persistence.volumes }}
+{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }}
+{{- end }}
+      {{- if .Values.controller.installPlugins }}
+      {{- if .Values.controller.overwritePluginsFromImage }}
+      - name: plugins
+        emptyDir: {}
+      {{- end }}
+      {{- end }}
+      {{- if and .Values.controller.initScripts .Values.controller.initConfigMap }}
+      - name: init-scripts
+        projected:
+          sources:
+          - configMap:
+              name: {{ template "jenkins.fullname" . }}-init-scripts
+          - configMap:
+              name: {{ .Values.controller.initConfigMap }}
+      {{- else if .Values.controller.initConfigMap }}
+      - name: init-scripts
+        configMap:
+          name: {{ .Values.controller.initConfigMap }}
+      {{- else if .Values.controller.initScripts }}
+      - name: init-scripts
+        configMap:
+          name: {{ template "jenkins.fullname" . }}-init-scripts
+      {{- end }}
+      - name: jenkins-config
+        configMap:
+          name: {{ template "jenkins.fullname" . }}
+      {{- if .Values.controller.installPlugins }}
+      - name: plugin-dir
+        emptyDir: {}
+      {{- end }}
+      {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
+      - name: jenkins-secrets
+        projected:
+          sources:
+          {{- if .Values.controller.additionalSecrets }}
+          - secret:
+              name: {{ template "jenkins.fullname" . }}-additional-secrets
+          {{- end }}
+          {{- if .Values.controller.additionalExistingSecrets }}
+          {{- range $key, $value := .Values.controller.additionalExistingSecrets }}
+          - secret:
+              name: {{ tpl $value.name $ }}
+              items:
+                - key: {{ tpl $value.keyName $ }}
+                  path: {{ tpl $value.name $ }}-{{ tpl $value.keyName $ }}
+          {{- end }}
+          {{- end }}
+          {{- if .Values.controller.admin.createSecret }}
+          - secret:
+              name: {{ .Values.controller.admin.existingSecret | default (include "jenkins.fullname" .) }}
+              items:
+                - key: {{ .Values.controller.admin.userKey | default "jenkins-admin-user" }}
+                  path: chart-admin-username
+                - key: {{ .Values.controller.admin.passwordKey | default "jenkins-admin-password" }}
+                  path: chart-admin-password
+        {{- end }}
+        {{- if .Values.controller.existingSecret }}
+          - secret:
+              name: {{ .Values.controller.existingSecret }}
+        {{- end }}
+      {{- end }}
+      - name: jenkins-cache
+        emptyDir: {}
+      {{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }}
+      - name: jenkins-home
+      {{- if .Values.persistence.enabled }}
+        persistentVolumeClaim:
+          claimName: {{ .Values.persistence.existingClaim | default (include "jenkins.fullname" .) }}
+      {{- else }}
+        emptyDir: {}
+      {{- end -}}
+      {{- end }}
+      - name: sc-config-volume
+        emptyDir: {}
+      - name: tmp-volume
+        emptyDir: {}
+
+      {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
+      - name: jenkins-https-keystore
+        secret:
+          secretName: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks  {{ end }}
+          items:
+          - key: {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretKey }}
+            path: {{ .Values.controller.httpsKeyStore.fileName }}
+      {{- end }}
+
+{{- if .Values.controller.imagePullSecretName }}
+      imagePullSecrets:
+      - name: {{ .Values.controller.imagePullSecretName }}
+{{- end -}}