From 9bab5f294c7905662ac0cff3926d6a739739097e Mon Sep 17 00:00:00 2001 From: robfrank Date: Wed, 29 Apr 2026 18:53:55 +0200 Subject: [PATCH 1/7] chore(helm): bump chart and app version to 26.5.1 --- k8s/helm/Chart.yaml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/k8s/helm/Chart.yaml b/k8s/helm/Chart.yaml index 0b83e1851e..2027be0c62 100644 --- a/k8s/helm/Chart.yaml +++ b/k8s/helm/Chart.yaml @@ -3,23 +3,8 @@ name: arcadedb description: | A Helm chart for ArcadeDB -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. type: application -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 25.7.1 +version: 26.5.1 -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: "25.7.1" +appVersion: "26.5.1" From e405e4132693395b98666cd6283ba889a520c52f Mon Sep 17 00:00:00 2001 From: robfrank Date: Wed, 29 Apr 2026 18:56:00 +0200 Subject: [PATCH 2/7] feat(helm): restructure values.yaml - fix keys, add persistence/networkPolicy/security defaults --- k8s/helm/values.yaml | 265 +++++++++++++++++++++---------------------- 1 file changed, 127 insertions(+), 138 deletions(-) diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml index 26f25fc0cb..53a27c5884 100644 --- a/k8s/helm/values.yaml +++ b/k8s/helm/values.yaml @@ -1,218 +1,204 @@ -## @param replicaCount This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ -## +## @param replicaCount Number of replicas. Values > 1 enable Raft HA automatically. replicaCount: 1 ## @section arcadedb arcadedb: - ## @param arcadedb.databaseDirectory Enable persistence by updating this and volume/Mounts + ## @param arcadedb.databaseDirectory Database storage directory inside the container databaseDirectory: "/home/arcadedb/databases" - ## @param arcadedb.defaultDatabases Default databases - defaultDatabases: "Universe[foo:bar]" - ## @param arcadedb.extraCommands Any extra commands to pass to ArcadeDB startup + ## @param arcadedb.defaultDatabases Databases to create at startup. Empty = none. + ## Example: "Universe[admin:password]" + defaultDatabases: "" + ## @param arcadedb.extraCommands Extra JVM -D arguments appended to the startup command extraCommands: - - -Darcadedb.server.mode=development # development | production - ## @param arcadedb.extraEnvironment Additional environment variables to pass to the ArcadeDB container + - -Darcadedb.server.mode=production + ## @param arcadedb.extraEnvironment Additional environment variables for the container extraEnvironment: [] + ## @section arcadedb.credentials credentials: - ## @section arcadedb.credentials.rootPassword rootPassword: - ## @section arcadedb.credentials.secret - ## If the secret is null, a new one called 'arcadedb-credentials-secret' will be created - ## NOTE: If you are using `helm template` ie like ArgoCD does, each time the generated secret - ## will be updated! If your auth flow is automated thru the secret name then maybe that's okay. - ## Otherwise, you may be better off specifying the secret thru other means. + ## If secret.name is null a random 32-char secret named 'arcadedb-credentials-secret' is + ## auto-generated. NOTE: helm template (e.g. ArgoCD) regenerates the secret each render. + ## For GitOps workflows supply your own secret and set name + key. secret: - ## @param arcadedb.credentials.rootPassword.secret.name Name of existing secret + ## @param arcadedb.credentials.rootPassword.secret.name Existing secret name (null = auto-generate) name: null - ## @param arcadedb.credentials.rootPassword.secret.key Key to use in existing secret + ## @param arcadedb.credentials.rootPassword.secret.key Key inside the existing secret key: null - ## @section arcadedb.plugins in this section you can enable and configure the plugins available in ArcadeDB. + ## @section arcadedb.plugins + ## Uncomment and configure to enable wire-protocol plugins. plugins: {} # gremlin: - ## @param arcadedb.plugins.gremlin.enabled Enable Gremlin plugin - # enabled: true - ## @param arcadedb.plugins.gremlin.port Port for Gremlin HTTP service - # port: 8182 + # enabled: true + # port: 8182 # postgres: - ## @param arcadedb.plugins.postgres.enabled Enable Postgres plugin - # enabled: true - ## @param arcadedb.plugins.postgres.port Port for Postgres service - # port: 5432 + # enabled: true + # port: 5432 # mongo: - ## @param arcadedb.plugins.mongo.enabled Enable Mongo plugin - # enabled: false - ## @param arcadedb.plugins.mongo.port Port for Mongo service - # port: 27017 + # enabled: false + # port: 27017 # redis: - ## @param arcadedb.plugins.redis.enabled Enable Redis plugin - # enabled: false - ## @param arcadedb.plugins.redis.port Port for Redis service - # port: 6379 + # enabled: false + # port: 6379 # prometheus: - ## @param arcadedb.plugins.prometheus.enabled Enable Prometheus plugin - # enabled: false - ## The following plugin is commented out as they are an example how configure a custom plugin. - ## custom: - ## @param arcadedb.plugins.custom.enabled Enable custom plugin - ## enabled: false - ## @param arcadedb.plugins.custom.port Port for custom service - ## port: 1234 - ## @param arcadedb.plugins.custom.class Class name for custom plugin - ## class: com.example.CustomPlugin + # enabled: false + ## Custom plugin example: + # myPlugin: + # enabled: true + # port: 1234 + # class: com.example.MyPlugin ## @section image -## This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ image: - ## @param image.registry Registry for image + ## @param image.registry Container registry registry: arcadedata - ## @param image.repository Image repo + ## @param image.repository Image repository repository: arcadedb - ## @param image.pullPolicy This sets the pull policy for images. + ## @param image.pullPolicy Image pull policy pullPolicy: IfNotPresent - ## @param image.tag Overrides the image tag whose default is the chart appVersion. + ## @param image.tag Image tag. Defaults to chart appVersion. tag: "" -## @param imagePullSecrets This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +## @param imagePullSecrets Secrets for pulling from private registries imagePullSecrets: [] -## @param nameOverride This is to override the chart name. +## @param nameOverride Override chart name nameOverride: "" -## @param fullnameOverride +## @param fullnameOverride Override fully-qualified app name fullnameOverride: "" -## @section This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +## @section serviceAccount serviceAccount: - ## @param serviceAccount.create Specifies whether a service account should be created + ## @param serviceAccount.create Create a ServiceAccount create: true - ## @param serviceAccount.automount Automatically mount a ServiceAccount's API credentials? - automount: true - ## @param serviceAccount.annotations Annotations to add to the service account + ## @param serviceAccount.automount Mount the ServiceAccount token into pods. + ## ArcadeDB does not call the Kubernetes API - keep false. + automount: false + ## @param serviceAccount.annotations Annotations for the ServiceAccount annotations: {} - ## @param serviceAccount.name The name of the service account to use. - ## If not set and create is true, a name is generated using the fullname template + ## @param serviceAccount.name ServiceAccount name. Auto-generated when empty. name: "" -## @param podAnnotations This is for setting Kubernetes Annotations to a Pod. -## For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## @param podAnnotations Annotations added to every pod podAnnotations: {} -## @param podLabels This is for setting Kubernetes Labels to a Pod. -## For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## @param podLabels Labels added to every pod podLabels: {} -## @param podSecurityContext -podSecurityContext: {} - # fsGroup: 2000 - -## @param securityContext -securityContext: {} - # capabilities: - # drop: - # - ALL - # readOnlyRootFilesystem: true - # runAsNonRoot: true - # runAsUser: 1000 - -## @section This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ +## @param podSecurityContext Pod-level security context. +## UID/GID 1000 matches the 'arcadedb' user created in the Docker image. +podSecurityContext: + runAsNonRoot: true + fsGroup: 1000 + +## @param securityContext Container-level security context +securityContext: + runAsUser: 1000 + runAsGroup: 1000 + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] + +## @section service service: - ## @section http + ## @section service.http http: - ## @param service.http.type This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types - type: LoadBalancer - ## @param service.http.port This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + ## @param service.http.type Service type. Use LoadBalancer or configure ingress for external access. + type: ClusterIP + ## @param service.http.port HTTP / Studio port port: 2480 - ## @section rpc + ## @section service.rpc rpc: - ## @param service.rpc.port This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports - port: 2424 + ## @param service.rpc.port Raft gRPC port (new ha-raft subsystem). Was 2424 in old binary-protocol HA. + port: 2434 -## @section ingress This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ -## TODO: This is probably broken, a mismatch between selectors in the headless service vs http service. -## At least it doesn't seem to work correctly when using Traefik annotations. +## @section ingress ingress: - ## @param ingress.enabled + ## @param ingress.enabled Enable Ingress enabled: false - ## @param ingress.className + ## @param ingress.className IngressClass name className: "" - ## @param ingress.annotations + ## @param ingress.annotations Ingress annotations annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" ## @section ingress.hosts hosts: - ## @param ingress.hosts[0].host - host: chart-example.local - ## @section ingress.hosts[0].paths paths: - ## @param ingress.hosts[0].paths[0].path - path: / - ## @param ingress.hosts[0].paths[0].pathType pathType: ImplementationSpecific - ## @param ingress.tls + ## @param ingress.tls TLS configuration tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local -## @param resources +## @param resources Resource requests and limits. +## Commented out by default for dev/Minikube compatibility. +## Tune and uncomment for production. resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -## @section This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +# resources: +# requests: +# cpu: 500m +# memory: 2Gi # matches -Xms2G set by ARCADEDB_OPTS_MEMORY in the Docker image +# limits: +# memory: 4Gi # no CPU limit - avoids throttling JVM GC pauses + +## @section livenessProbe livenessProbe: - ## @section livenessProbe.httpGet httpGet: - ## @param livenessProbe.httpGet.path path: /api/v1/ready - ## @param livenessProbe.httpGet.port port: http -## @section This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ + +## @section readinessProbe readinessProbe: - ## @section readinessProbe.httpGet httpGet: - ## @param readinessProbe.httpGet.path path: /api/v1/ready - ## @param readinessProbe.httpGet.port port: http -## @section This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ +## @section autoscaling autoscaling: - ## @param autoscaling.enabled + ## @param autoscaling.enabled Enable HorizontalPodAutoscaler. + ## When enabled, the HA server list is pre-sized to maxReplicas so KubernetesAutoJoin + ## can add pods dynamically. minReplicas must satisfy Raft quorum: >= floor(maxReplicas/2)+1. enabled: false - ## @param autoscaling.minReplicas + ## @param autoscaling.minReplicas Minimum replicas. Must satisfy Raft quorum when HA is active. minReplicas: 1 - ## @param autoscaling.maxReplicas - maxReplicas: 100 - ## @param autoscaling.targetCPUUtilizationPercentage + ## @param autoscaling.maxReplicas Maximum replicas + maxReplicas: 5 + ## @param autoscaling.targetCPUUtilizationPercentage Target CPU utilization targetCPUUtilizationPercentage: 80 # targetMemoryUtilizationPercentage: 80 -## @param volumes Additional volumes on the output Deployment definition. +## @section persistence +persistence: + ## @param persistence.enabled Persist the database directory with a PVC. + ## Set to false only for ephemeral/dev deployments - all data is lost on pod restart. + enabled: true + ## @param persistence.size PVC size + size: 8Gi + ## @param persistence.accessMode PVC access mode + accessMode: ReadWriteOnce + ## @param persistence.storageClass StorageClass name. Empty = cluster default. + storageClass: "" + +## @param volumes Additional pod volumes volumes: [] -# - name: foo -# secret: -# secretName: mysecret -# optional: false +# - name: arcadedb-config +# configMap: +# name: my-arcadedb-config -## @param volumeMounts Additional volumeMounts on the output Deployment definition. +## @param volumeMounts Additional container volume mounts volumeMounts: [] -# - name: foo -# mountPath: "/etc/foo" +# - name: arcadedb-config +# mountPath: /home/arcadedb/config # readOnly: true -## @section volumeClaimTemplates This section is for setting up volumeClaimTemplates in StatefulSet. More information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#volume-claim-templates +## @param volumeClaimTemplates Extra StatefulSet volumeClaimTemplates (for config, replication, backups, log). +## The database-data PVC is controlled by persistence.enabled above. volumeClaimTemplates: [] # - metadata: -# name: arcadedb-data +# name: arcadedb-config # spec: # accessModes: # - ReadWriteOnce @@ -220,29 +206,32 @@ volumeClaimTemplates: [] # requests: # storage: 1Gi -## @param nodeSelector +## @param nodeSelector Node selector nodeSelector: {} -## @param tolerations +## @param tolerations Tolerations tolerations: [] ## @section affinity affinity: - ## @section Set the anti-affinity selector scope to arcadedb servers. podAntiAffinity: - ## @section preferredDuringSchedulingIgnoredDuringExecution preferredDuringSchedulingIgnoredDuringExecution: - ## @param affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].weight - weight: 100 - ## @skip affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm podAffinityTerm: labelSelector: matchExpressions: - - key: app + - key: app.kubernetes.io/name operator: In values: - arcadedb topologyKey: kubernetes.io/hostname -## @param extraManifests - Include any amount of extra arbitrary manifests +## @param extraManifests Arbitrary extra Kubernetes manifests to include extraManifests: {} + +## @section networkPolicy +networkPolicy: + ## @param networkPolicy.enabled Create NetworkPolicy resources. + ## When enabled: HTTP (2480) is open to all cluster pods; Raft gRPC (2434) is restricted + ## to ArcadeDB pods only. Recommended for production multi-tenant clusters. + enabled: false From cc96db1a113abdad65a0f749bef390d9e356367e Mon Sep 17 00:00:00 2001 From: robfrank Date: Wed, 29 Apr 2026 19:12:35 +0200 Subject: [PATCH 3/7] fix(helm): update nodenames helper - port 2434, HPA-aware list sizing --- k8s/helm/templates/_helpers.tpl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/k8s/helm/templates/_helpers.tpl b/k8s/helm/templates/_helpers.tpl index 16eb8fec07..211a74f6df 100644 --- a/k8s/helm/templates/_helpers.tpl +++ b/k8s/helm/templates/_helpers.tpl @@ -71,14 +71,19 @@ Create the name of the service account to use {{- end }} {{/* -Create a list of pod names based the number of replica. +Create a comma-separated list of StatefulSet pod FQDNs for the Raft HA server list. +When HPA is enabled, the list is sized to autoscaling.maxReplicas so that +KubernetesAutoJoin can resolve any pod ordinal up to the maximum scale. */}} {{- define "arcadedb.nodenames" -}} {{- $replicas := int .Values.replicaCount -}} +{{- if and .Values.autoscaling.enabled (gt (int .Values.autoscaling.maxReplicas) $replicas) -}} + {{- $replicas = int .Values.autoscaling.maxReplicas -}} +{{- end -}} {{- $names := list -}} {{- $fullname := (include "arcadedb.fullname" .) -}} {{- $k8sSuffix := (include "arcadedb.k8sSuffix" .) -}} -{{- $rpcPort := int (default "2424" .Values.service.rpc.port) -}} +{{- $rpcPort := int .Values.service.rpc.port -}} {{- range $i, $_ := until $replicas }} {{- $names = append $names (printf "%s-%d%s:%d" $fullname $i $k8sSuffix $rpcPort) }} {{- end }} From 9f07482e9e945376dbd61d79fc457bb73c70cca6 Mon Sep 17 00:00:00 2001 From: robfrank Date: Thu, 30 Apr 2026 09:13:59 +0200 Subject: [PATCH 4/7] fix(helm): fix critical HA bugs, security hardening, persistence, NetworkPolicy - Fix env-var expansion: use $(HOSTNAME)/$(rootPassword) Kubernetes substitution syntax - ${VAR} shell syntax is not expanded in exec-form command arrays - Fix Raft port: service.rpc.port default changed from 2424 to 2434 (ha-raft gRPC) - Remove -Darcadedb.ha.replicationIncomingHost (not a valid ha-raft property) - Make HA conditional: args only emitted when replicaCount > 1 or autoscaling.enabled - Add publishNotReadyAddresses: true to headless service (prevents bootstrap deadlock) - Fix ingress backend: point to -http ClusterIP service, fix service.http.port key - Add Raft quorum guard to HPA: fail when minReplicas < floor(maxReplicas/2)+1 - Add opt-in NetworkPolicy: HTTP open to cluster, Raft gRPC restricted to ArcadeDB pods - Security: runAsNonRoot, drop ALL caps, serviceAccount.automount=false, ClusterIP default - Persistence: volumeClaimTemplate for arcadedb-data enabled by default (8Gi) - HPA: nodenames helper sized to maxReplicas for KubernetesAutoJoin scale-up support - Fix NOTES.txt port references, add ephemeral data warning - Guard extra-manifests.yaml bare --- separator - Update README: fix stale defaults (port, service type, mode), add missing sections Closes #4034 Co-Authored-By: Claude Sonnet 4.6 --- k8s/helm/README.md | 68 +++++++++++++++---------- k8s/helm/templates/NOTES.txt | 13 +++-- k8s/helm/templates/extra-manifests.yaml | 2 + k8s/helm/templates/hpa.yaml | 8 +++ k8s/helm/templates/ingress.yaml | 4 +- k8s/helm/templates/networkpolicy.yaml | 39 ++++++++++++++ k8s/helm/templates/service.yaml | 8 +-- k8s/helm/templates/statefulset.yaml | 52 ++++++++++++++----- 8 files changed, 143 insertions(+), 51 deletions(-) create mode 100644 k8s/helm/templates/networkpolicy.yaml diff --git a/k8s/helm/README.md b/k8s/helm/README.md index cfd0a9c8ac..d65768a8aa 100644 --- a/k8s/helm/README.md +++ b/k8s/helm/README.md @@ -35,10 +35,10 @@ The command removes all the Kubernetes components associated with the chart and | Name | Description | Value | |------------------------------|--------------------------------------------------------------------|------------------------------------------| -| `arcadedb.databaseDirectory` | Enable persistence by updating this and volume/Mounts | `/home/arcadedb/databases` | -| `arcadedb.defaultDatabases` | Default databases | `Universe[foo:bar]` | -| `arcadedb.extraCommands` | Any extra commands to pass to ArcadeDB startup | `["-Darcadedb.server.mode=development"]` | -| `arcadedb.extraEnvironment` | Additional environment variables to pass to the ArcadeDB container | `[]` | +| `arcadedb.databaseDirectory` | Database storage directory inside the container | `/home/arcadedb/databases` | +| `arcadedb.defaultDatabases` | Databases to create at startup. Empty = none. | `""` | +| `arcadedb.extraCommands` | Extra JVM -D arguments appended to the startup command | `["-Darcadedb.server.mode=production"]` | +| `arcadedb.extraEnvironment` | Additional environment variables to pass to the ArcadeDB container | `[]` | ### arcadedb.credentials @@ -67,14 +67,14 @@ The command removes all the Kubernetes components associated with the chart and | Name | Description | Value | |------------------------------|---------------------------------------------------------|--------| -| `serviceAccount.create` | Specifies whether a service account should be created | `true` | -| `serviceAccount.automount` | Automatically mount a ServiceAccount's API credentials? | `true` | -| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | -| `serviceAccount.name` | The name of the service account to use. | `""` | -| `podAnnotations` | This is for setting Kubernetes Annotations to a Pod. | `{}` | -| `podLabels` | This is for setting Kubernetes Labels to a Pod. | `{}` | -| `podSecurityContext` | | `{}` | -| `securityContext` | | `{}` | +| `serviceAccount.create` | Specifies whether a service account should be created | `true` | +| `serviceAccount.automount` | Mount the ServiceAccount token into pods. ArcadeDB does not call the Kubernetes API - keep false. | `false` | +| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | +| `serviceAccount.name` | The name of the service account to use. | `""` | +| `podAnnotations` | Annotations added to every pod. | `{}` | +| `podLabels` | Labels added to every pod. | `{}` | +| `podSecurityContext` | Pod-level security context. UID/GID 1000 matches the arcadedb user in the Docker image. | `{runAsNonRoot: true, fsGroup: 1000}` | +| `securityContext` | Container-level security context. | `{runAsUser: 1000, runAsGroup: 1000, allowPrivilegeEscalation: false, capabilities.drop: [ALL]}` | ### This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ @@ -82,14 +82,14 @@ The command removes all the Kubernetes components associated with the chart and | Name | Description | Value | |---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------| -| `service.http.type` | This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types | `LoadBalancer` | +| `service.http.type` | Service type. Use LoadBalancer or configure ingress for external access. | `ClusterIP` | | `service.http.port` | This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports | `2480` | ### rpc | Name | Description | Value | |--------------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------| -| `service.rpc.port` | This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports | `2424` | +| `service.rpc.port` | Raft gRPC port (ha-raft subsystem). | `2434` | ### ingress This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ @@ -136,13 +136,28 @@ The command removes all the Kubernetes components associated with the chart and | Name | Description | Value | |----------------------------------------------|-----------------------------------------------------------------------|---------| -| `autoscaling.enabled` | | `false` | -| `autoscaling.minReplicas` | | `1` | -| `autoscaling.maxReplicas` | | `100` | -| `autoscaling.targetCPUUtilizationPercentage` | | `80` | +| `autoscaling.enabled` | Enable HorizontalPodAutoscaler. When enabled, server list is pre-sized to maxReplicas for KubernetesAutoJoin. | `false` | +| `autoscaling.minReplicas` | Minimum replicas. Must satisfy Raft quorum when HA is active: >= floor(maxReplicas/2)+1. | `1` | +| `autoscaling.maxReplicas` | Maximum replicas. Chart enforces quorum guard at render time. | `5` | +| `autoscaling.targetCPUUtilizationPercentage` | | `80` | | `volumes` | Additional volumes on the output StatefulSet definition. | `[]` | | `volumeMounts` | Additional volumeMounts on the output StatefulSet definition. | `[]` | -| `volumeClaimTemplates` | Defines volumeClaimTemplates for the StatefulSet. | `[]` | +| `volumeClaimTemplates` | Extra StatefulSet volumeClaimTemplates (the database PVC is controlled by `persistence.enabled`). | `[]` | + +### persistence + +| Name | Description | Value | +|----------------------------|-----------------------------------------------------------------------------------------------------|-----------------| +| `persistence.enabled` | Persist the database directory with a PVC. Set false only for ephemeral/dev deployments. | `true` | +| `persistence.size` | PVC size. | `8Gi` | +| `persistence.accessMode` | PVC access mode. | `ReadWriteOnce` | +| `persistence.storageClass` | StorageClass name. Empty string uses the cluster default. | `""` | + +### networkPolicy + +| Name | Description | Value | +|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------|---------| +| `networkPolicy.enabled` | Create NetworkPolicy resources. HTTP (2480) open to all cluster pods; Raft gRPC (2434) restricted to ArcadeDB pods only. | `false` | | `nodeSelector` | | `{}` | | `tolerations` | | `[]` | @@ -171,9 +186,9 @@ helm install my-arcadedb ./arcadedb -f values.yaml ## Persistence -The ArcadeDB image stores data at the `/opt/arcadedb/databases` path of the container. By default, a PersistentVolumeClaim is -created and mounted to this directory. If you want to disable persistence, set `persistence.enabled` to `false`. Data will then be -stored in an emptyDir, which is erased when the Pod is terminated. +The ArcadeDB image stores data at `/home/arcadedb/databases` inside the container. By default (`persistence.enabled: true`), a +PersistentVolumeClaim named `arcadedb-data` is created and mounted at that path. Set `persistence.enabled` to `false` only for +ephemeral or development deployments - data will be written to the container's writable layer and lost when the Pod is deleted. ## Ingress @@ -190,16 +205,15 @@ ingress: ## Resources -The resource requests and limits can be set by specifying the `resources` parameter. The default values are: +Resource requests and limits are unset by default for dev/Minikube compatibility. For production, set them via: ```yaml resources: requests: - cpu: 100m - memory: 256Mi - limits: cpu: 500m - memory: 512Mi + memory: 2Gi # matches -Xms2G set by ARCADEDB_OPTS_MEMORY in the Docker image + limits: + memory: 4Gi # no CPU limit - avoids throttling JVM GC pauses ``` ## Notes diff --git a/k8s/helm/templates/NOTES.txt b/k8s/helm/templates/NOTES.txt index 85badb3f47..6c89cee459 100644 --- a/k8s/helm/templates/NOTES.txt +++ b/k8s/helm/templates/NOTES.txt @@ -6,17 +6,22 @@ {{- end }} {{- end }} {{- else if contains "NodePort" .Values.service.http.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "arcadedb.fullname" . }}) + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "arcadedb.fullname" . }}-http) export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT {{- else if contains "LoadBalancer" .Values.service.http.type }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "arcadedb.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "arcadedb.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} + You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "arcadedb.fullname" . }}-http' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "arcadedb.fullname" . }}-http --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.http.port }} {{- else if contains "ClusterIP" .Values.service.http.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "arcadedb.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") echo "Visit http://127.0.0.1:8080 to use your application" kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT {{- end }} +{{- if not .Values.persistence.enabled }} + +WARNING: persistence.enabled is false. Database data is EPHEMERAL and will be lost when pods restart. + Set persistence.enabled=true (the default) for any non-ephemeral deployment. +{{- end }} diff --git a/k8s/helm/templates/extra-manifests.yaml b/k8s/helm/templates/extra-manifests.yaml index 0f1cfaaed5..5d0f3ed8a6 100644 --- a/k8s/helm/templates/extra-manifests.yaml +++ b/k8s/helm/templates/extra-manifests.yaml @@ -1,3 +1,4 @@ +{{- if .Values.extraManifests }} --- {{- range $_key, $value := .Values.extraManifests }} @@ -8,3 +9,4 @@ --- {{- end }} +{{- end }} diff --git a/k8s/helm/templates/hpa.yaml b/k8s/helm/templates/hpa.yaml index b06c4e7993..bb0275b7f0 100644 --- a/k8s/helm/templates/hpa.yaml +++ b/k8s/helm/templates/hpa.yaml @@ -1,4 +1,12 @@ {{- if .Values.autoscaling.enabled }} +{{- if or (gt (int .Values.replicaCount) 1) .Values.autoscaling.enabled }} +{{- $maxReplicas := int .Values.autoscaling.maxReplicas }} +{{- $minReplicas := int .Values.autoscaling.minReplicas }} +{{- $quorum := add (div $maxReplicas 2) 1 }} +{{- if lt $minReplicas (int $quorum) }} +{{- fail (printf "autoscaling.minReplicas (%d) must be >= floor(maxReplicas/2)+1 (%d) to maintain Raft quorum with maxReplicas=%d. Increase minReplicas or decrease maxReplicas." $minReplicas (int $quorum) $maxReplicas) }} +{{- end }} +{{- end }} apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: diff --git a/k8s/helm/templates/ingress.yaml b/k8s/helm/templates/ingress.yaml index adbcfe8bd6..2e5526df08 100644 --- a/k8s/helm/templates/ingress.yaml +++ b/k8s/helm/templates/ingress.yaml @@ -35,9 +35,9 @@ spec: {{- end }} backend: service: - name: {{ include "arcadedb.fullname" $ }} + name: {{ include "arcadedb.fullname" $ }}-http port: - number: {{ $.Values.service.port }} + number: {{ $.Values.service.http.port }} {{- end }} {{- end }} {{- end }} diff --git a/k8s/helm/templates/networkpolicy.yaml b/k8s/helm/templates/networkpolicy.yaml new file mode 100644 index 0000000000..27f5d3360e --- /dev/null +++ b/k8s/helm/templates/networkpolicy.yaml @@ -0,0 +1,39 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "arcadedb.fullname" . }}-http + labels: + {{- include "arcadedb.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "arcadedb.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + - ports: + - port: {{ .Values.service.http.port }} + protocol: TCP +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "arcadedb.fullname" . }}-raft + labels: + {{- include "arcadedb.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "arcadedb.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + {{- include "arcadedb.selectorLabels" . | nindent 14 }} + ports: + - port: {{ .Values.service.rpc.port }} + protocol: TCP +{{- end }} diff --git a/k8s/helm/templates/service.yaml b/k8s/helm/templates/service.yaml index 9ce63f9dcf..aa9b7a4868 100644 --- a/k8s/helm/templates/service.yaml +++ b/k8s/helm/templates/service.yaml @@ -17,10 +17,9 @@ spec: --- {{/* -This is a "headless" service for the arcadedb which exists to allow discovery of the set of -member pods (masters). The CNAME of this service points to SRV records - one for each Pod that -is Running and Ready). Read more in the Kubernetes docs: -https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/ +Headless service for StatefulSet pod DNS discovery. +publishNotReadyAddresses: true ensures DNS entries exist during bootstrap +before readiness probes pass - required to avoid HA bootstrap deadlock. */}} apiVersion: v1 kind: Service @@ -30,6 +29,7 @@ metadata: {{- include "arcadedb.labels" . | nindent 4 }} spec: clusterIP: None + publishNotReadyAddresses: true ports: - port: {{ .Values.service.http.port }} targetPort: http diff --git a/k8s/helm/templates/statefulset.yaml b/k8s/helm/templates/statefulset.yaml index eddb228e03..8817e63c16 100644 --- a/k8s/helm/templates/statefulset.yaml +++ b/k8s/helm/templates/statefulset.yaml @@ -45,18 +45,23 @@ spec: - name: http containerPort: {{ .Values.service.http.port }} protocol: TCP + - name: rpc + containerPort: {{ .Values.service.rpc.port }} + protocol: TCP command: - bin/server.sh - -Darcadedb.dumpConfigAtStartup=true - - -Darcadedb.server.name=${HOSTNAME} - - -Darcadedb.server.rootPassword=${rootPassword} + - -Darcadedb.server.name=$(HOSTNAME) + - -Darcadedb.server.rootPassword=$(rootPassword) - -Darcadedb.server.databaseDirectory={{ .Values.arcadedb.databaseDirectory }} - -Darcadedb.server.defaultDatabases={{ .Values.arcadedb.defaultDatabases }} + {{- if or (gt (int .Values.replicaCount) 1) .Values.autoscaling.enabled }} - -Darcadedb.ha.enabled=true - - -Darcadedb.ha.replicationIncomingHost=0.0.0.0 - - -Darcadedb.ha.serverList={{ include "arcadedb.nodenames" . }} - -Darcadedb.ha.k8s=true - -Darcadedb.ha.k8sSuffix={{ include "arcadedb.k8sSuffix" . }} + - -Darcadedb.ha.serverList={{ include "arcadedb.nodenames" . }} + - -Darcadedb.ha.raftPort={{ .Values.service.rpc.port }} + {{- end }} {{- with .Values.arcadedb.extraCommands }} {{- toYaml . | nindent 12 }} {{- end }} @@ -73,11 +78,19 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} - {{- with .Values.volumeMounts }} volumeMounts: + {{- if .Values.persistence.enabled }} + - name: arcadedb-data + mountPath: {{ .Values.arcadedb.databaseDirectory }} + {{- end }} + {{- with .Values.volumeMounts }} {{- toYaml . | nindent 12 }} - {{- end }} + {{- end }} env: + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name - name: POD_ID valueFrom: fieldRef: @@ -87,19 +100,17 @@ spec: valueFrom: secretKeyRef: name: {{ .Values.arcadedb.credentials.rootPassword.secret.name }} - {{- if .Values.arcadedb.credentials.rootPassword.secret.key }} key: {{ .Values.arcadedb.credentials.rootPassword.secret.key }} - {{- end }} optional: false - {{- else }} {{/* Use auto generated secret then */}} + {{- else }} valueFrom: secretKeyRef: name: arcadedb-credentials-secret key: rootPassword {{- end }} - {{- with .Values.arcadedb.extraEnvironment }} - {{- toYaml . | nindent 12 }} - {{- end }} + {{- with .Values.arcadedb.extraEnvironment }} + {{- toYaml . | nindent 12 }} + {{- end }} {{- with .Values.volumes }} volumes: {{- toYaml . | nindent 8 }} @@ -116,7 +127,20 @@ spec: tolerations: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.volumeClaimTemplates }} volumeClaimTemplates: + {{- if .Values.persistence.enabled }} + - metadata: + name: arcadedb-data + spec: + accessModes: + - {{ .Values.persistence.accessMode }} + {{- if .Values.persistence.storageClass }} + storageClassName: {{ .Values.persistence.storageClass }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- end }} + {{- with .Values.volumeClaimTemplates }} {{- toYaml . | nindent 4 }} - {{- end }} + {{- end }} From fb5cbf62f397f72db6e62c812a5f7d8cf6e63dcb Mon Sep 17 00:00:00 2001 From: robfrank Date: Thu, 30 Apr 2026 09:36:47 +0200 Subject: [PATCH 5/7] docs: add spec for arcadedb-helm dedicated repository --- ...-04-29-helm-chart-dedicated-repo-design.md | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-29-helm-chart-dedicated-repo-design.md diff --git a/docs/superpowers/specs/2026-04-29-helm-chart-dedicated-repo-design.md b/docs/superpowers/specs/2026-04-29-helm-chart-dedicated-repo-design.md new file mode 100644 index 0000000000..6684e2a326 --- /dev/null +++ b/docs/superpowers/specs/2026-04-29-helm-chart-dedicated-repo-design.md @@ -0,0 +1,156 @@ +# Helm Chart - Dedicated Repository + +**Status:** approved +**Date:** 2026-04-29 + +--- + +## Goals + +Move the ArcadeDB Helm chart out of the main `arcadedb` monorepo into a dedicated `ArcadeData/arcadedb-helm` repository so that: + +- Users can install via standard `helm repo add` without cloning the monorepo +- The chart is discoverable on Artifact Hub (`helm search hub arcadedb`) +- The chart has an independent release lifecycle - chart-only fixes do not require a server release +- A published `index.yaml` is served via GitHub Pages at a stable URL + +Out of scope: changes to chart content (done in #4034), Docker Compose scenarios in `arcadedb-deployments`, OCI registry publishing. + +--- + +## Repository Structure + +New repo: `ArcadeData/arcadedb-helm` + +``` +arcadedb-helm/ +├── charts/ +│ └── arcadedb/ ← chart moved from k8s/helm/ in main repo +│ ├── Chart.yaml +│ ├── values.yaml +│ ├── README.md +│ └── templates/ +├── index.yaml ← auto-generated by CI, served via GitHub Pages +├── README.md ← helm repo add instructions + Artifact Hub badge +└── .github/ + └── workflows/ + ├── release.yml ← manual dispatch: bumps version, tags, packages, publishes + └── lint.yml ← runs on every PR and push to main +``` + +GitHub Pages is enabled on the `main` branch root (`/`). The stable repository URL is: + +``` +https://arcadedata.github.io/arcadedb-helm/ +``` + +Chart `.tgz` assets are attached to GitHub Releases (not stored in the repo tree). `index.yaml` points at those release asset URLs. + +--- + +## Release Workflow + +File: `.github/workflows/release.yml` + +**Trigger:** manual `workflow_dispatch` with two inputs: + +| Input | Required | Description | +|---|---|---| +| `version` | yes | Chart version to release, e.g. `26.5.2` | +| `app_version` | no | ArcadeDB server version, e.g. `26.5.1`. Leave blank to keep the current `appVersion` in `Chart.yaml`. | + +**Steps:** + +1. Validate `version` is a valid semver string - fail early with a clear message if not +2. Update `Chart.yaml`: set `version` to input; set `appVersion` to input if provided +3. `helm lint charts/arcadedb/` - abort if lint fails +4. `git commit Chart.yaml -m "chore(helm): release v"` +5. `git tag v` and push commit + tag +6. `helm/chart-releaser-action` - packages the chart, updates `index.yaml`, creates GitHub Release with `.tgz` as asset, pushes `index.yaml` to `main` + +**To release:** + +``` +GitHub → Actions → "Release" → Run workflow → version: 26.5.2 → Run +``` + +No manual tagging. No local commands needed. + +--- + +## PR Validation Workflow + +File: `.github/workflows/lint.yml` + +**Trigger:** push to `main`, all pull requests. + +Runs a matrix of `helm template` scenarios to catch regressions: + +| Scenario | Key flags | +|---|---| +| Default single-node | (none) | +| HA replicaCount=3 | `--set replicaCount=3` | +| HPA valid quorum | `--set autoscaling.enabled=true --set autoscaling.minReplicas=3 --set autoscaling.maxReplicas=5` | +| HPA quorum guard fires | `--set autoscaling.enabled=true --set autoscaling.minReplicas=1 --set autoscaling.maxReplicas=5` (expect failure) | +| Ingress enabled | `--set ingress.enabled=true` | +| NetworkPolicy enabled | `--set networkPolicy.enabled=true` | + +Plus `helm lint charts/arcadedb/`. + +--- + +## Artifact Hub Registration + +One-time manual step after the repo is created and the first chart version is published: + +1. Create or log in to an account on [artifacthub.io](https://artifacthub.io) +2. Add repository: type `Helm`, URL `https://arcadedata.github.io/arcadedb-helm/` +3. Copy the assigned `repositoryID` UUID +4. Add to `Chart.yaml`: + ```yaml + annotations: + artifacthub.io/repositoryID: "" + ``` +5. Commit and include in the first release + +After that, every release is auto-indexed within minutes. The chart appears in: +- `helm search hub arcadedb` +- Artifact Hub search results +- Google (Artifact Hub pages rank well for "arcadedb helm chart") + +--- + +## Main Repo Cleanup + +In `ArcadeData/arcadedb`: + +- Delete `k8s/helm/` entirely +- Replace with `k8s/README.md`: + +```markdown +# Kubernetes + +The ArcadeDB Helm chart has moved to its own repository: + +**https://github.com/ArcadeData/arcadedb-helm** + +Install: + +```bash +helm repo add arcadedb https://arcadedata.github.io/arcadedb-helm/ +helm repo update +helm install my-arcadedb arcadedb/arcadedb +``` +``` + +- Close issue #4034 with a comment pointing to the new repo (the refactor in that issue seeded the chart content that moves to the new repo) +- `arcadedb-deployments` is left as-is - no Helm content goes there + +--- + +## Versioning Convention + +| Field | Convention | +|---|---| +| `Chart.yaml: version` | Independent semver. Bumps for any chart change, including chart-only fixes. Format: matches `appVersion` on server releases, adds patch increments for chart-only fixes (e.g. server `26.5.1` → chart starts at `26.5.1`, chart fix → `26.5.2`). | +| `Chart.yaml: appVersion` | Tracks the ArcadeDB server release. Updated via the `app_version` workflow input when a new server version ships. | From d3ada153ab70fb2757066c0b57530c0149d1ae95 Mon Sep 17 00:00:00 2001 From: robfrank Date: Thu, 30 Apr 2026 09:43:08 +0200 Subject: [PATCH 6/7] docs: add implementation plan for arcadedb-helm dedicated repository Co-Authored-By: Claude Sonnet 4.6 --- .../2026-04-29-helm-chart-dedicated-repo.md | 548 ++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 docs/superpowers/plans/2026-04-29-helm-chart-dedicated-repo.md diff --git a/docs/superpowers/plans/2026-04-29-helm-chart-dedicated-repo.md b/docs/superpowers/plans/2026-04-29-helm-chart-dedicated-repo.md new file mode 100644 index 0000000000..33be11f691 --- /dev/null +++ b/docs/superpowers/plans/2026-04-29-helm-chart-dedicated-repo.md @@ -0,0 +1,548 @@ +# arcadedb-helm Dedicated Repository - Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Move the ArcadeDB Helm chart from `k8s/helm/` in the main monorepo into a new `ArcadeData/arcadedb-helm` GitHub repository with GitHub Pages serving, a manual-dispatch release workflow, PR lint validation, and Artifact Hub registration. + +**Architecture:** A new public GitHub repo hosts the chart under `charts/arcadedb/`. GitHub Pages serves `index.yaml` from the `gh-pages` branch (managed automatically by `helm/chart-releaser-action`). Releases are triggered manually via `workflow_dispatch` with a version input; the workflow bumps `Chart.yaml`, commits, tags, and publishes in one step. The main monorepo's `k8s/helm/` directory is replaced by a redirect `README.md`. + +**Tech Stack:** Helm v3, GitHub Actions, `helm/chart-releaser-action@v1.6.0`, `azure/setup-helm@v4`, GitHub Pages (`gh-pages` branch), Artifact Hub. + +--- + +## File Map + +**New repo `ArcadeData/arcadedb-helm`:** + +| File | Purpose | +|---|---| +| `charts/arcadedb/Chart.yaml` | Chart metadata - version bumped by release workflow | +| `charts/arcadedb/values.yaml` | Default values | +| `charts/arcadedb/README.md` | Chart-level documentation | +| `charts/arcadedb/templates/` | All template files (10 files) | +| `README.md` | Repo-level: `helm repo add` instructions + Artifact Hub badge | +| `LICENSE` | Apache 2.0 | +| `.gitignore` | Ignore `.cr-release-packages/` | +| `.github/workflows/lint.yml` | PR validation: lint + template matrix | +| `.github/workflows/release.yml` | Manual release: validate, bump, commit, tag, package, publish | + +**Existing repo `ArcadeData/arcadedb` (cleanup):** + +| File | Change | +|---|---| +| `k8s/helm/` | Deleted entirely | +| `k8s/README.md` | New redirect to arcadedb-helm repo | + +--- + +## Task 1: Create and initialize the arcadedb-helm repository + +**Context:** All steps in Tasks 1-6 are performed in the NEW `arcadedb-helm` repo, not the arcadedb monorepo. Choose a local parent directory (e.g. `~/projects/arcade/`) to clone into. + +**Files:** +- Create: `README.md` +- Create: `LICENSE` +- Create: `.gitignore` + +- [ ] **Step 1: Create the GitHub repository** + +```bash +gh repo create ArcadeData/arcadedb-helm \ + --public \ + --description "ArcadeDB Helm chart" \ + --clone +cd arcadedb-helm +``` + +Expected: repository created and cloned, you are now inside `arcadedb-helm/`. + +- [ ] **Step 2: Create `.gitignore`** + +```bash +cat > .gitignore << 'EOF' +.cr-release-packages/ +.helm/ +EOF +``` + +- [ ] **Step 3: Copy Apache 2.0 LICENSE from the main repo** + +```bash +curl -s https://raw.githubusercontent.com/ArcadeData/arcadedb/main/LICENSE > LICENSE +``` + +Expected: `LICENSE` file present, starts with `Apache License`. + +- [ ] **Step 4: Create the repo-level `README.md`** + +```markdown +# ArcadeDB Helm Chart + +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/arcadedb)](https://artifacthub.io/packages/helm/arcadedb/arcadedb) + +The official Helm chart for [ArcadeDB](https://arcadedb.com/), a multi-model database supporting SQL, Cypher, Gremlin, MongoDB, and Redis protocols. + +## Install + +```bash +helm repo add arcadedb https://arcadedata.github.io/arcadedb-helm/ +helm repo update +helm install my-arcadedb arcadedb/arcadedb +``` + +## Configuration + +See [charts/arcadedb/README.md](charts/arcadedb/README.md) and [charts/arcadedb/values.yaml](charts/arcadedb/values.yaml) for all available options. + +## Release + +New chart versions are published via the GitHub Actions Release workflow: + +``` +GitHub → Actions → Release → Run workflow → enter version → Run +``` + +## Contributing + +PRs welcome. The lint workflow runs on all pull requests. +``` + +- [ ] **Step 5: Commit and push** + +```bash +git add README.md LICENSE .gitignore +git commit -m "chore: initialize arcadedb-helm repository" +git push origin main +``` + +Expected: push succeeds, repo visible at `https://github.com/ArcadeData/arcadedb-helm`. + +--- + +## Task 2: Copy chart content + +**Context:** Still inside the `arcadedb-helm` directory. The source chart files are in the `arcadedb` monorepo at `k8s/helm/`. Adjust the source path to wherever you have the monorepo cloned. + +**Files:** +- Create: `charts/arcadedb/` (entire directory tree) + +- [ ] **Step 1: Create the charts directory and copy files** + +```bash +mkdir -p charts/arcadedb/templates + +# Adjust ARCADEDB_REPO to wherever the main repo is cloned +ARCADEDB_REPO=~/projects/arcade/arcadedb + +cp $ARCADEDB_REPO/k8s/helm/Chart.yaml charts/arcadedb/ +cp $ARCADEDB_REPO/k8s/helm/values.yaml charts/arcadedb/ +cp $ARCADEDB_REPO/k8s/helm/README.md charts/arcadedb/ +cp $ARCADEDB_REPO/k8s/helm/templates/* charts/arcadedb/templates/ +``` + +Expected: `charts/arcadedb/` contains `Chart.yaml`, `values.yaml`, `README.md`, and `templates/` with 10 files. + +- [ ] **Step 2: Verify the copy is complete** + +```bash +ls charts/arcadedb/templates/ +``` + +Expected output (10 files): +``` +_helpers.tpl hpa.yaml NOTES.txt secret.yaml statefulset.yaml +extra-manifests.yaml ingress.yaml networkpolicy.yaml service.yaml serviceaccount.yaml +``` + +- [ ] **Step 3: Lint to confirm the chart is valid** + +```bash +helm lint charts/arcadedb/ +``` + +Expected: `1 chart(s) linted, 0 chart(s) failed` + +- [ ] **Step 4: Commit** + +```bash +git add charts/ +git commit -m "feat: add arcadedb Helm chart (moved from ArcadeData/arcadedb k8s/helm/)" +git push origin main +``` + +--- + +## Task 3: Create the PR validation workflow + +**Files:** +- Create: `.github/workflows/lint.yml` + +- [ ] **Step 1: Create the workflow directory and file** + +```bash +mkdir -p .github/workflows +``` + +Create `.github/workflows/lint.yml` with this exact content: + +```yaml +name: Lint + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: v3.14.0 + + - name: Lint + run: helm lint charts/arcadedb/ + + - name: Template - default single-node + run: helm template test charts/arcadedb/ > /dev/null + + - name: Template - HA replicaCount=3 + run: helm template test charts/arcadedb/ --set replicaCount=3 > /dev/null + + - name: Template - HPA valid quorum + run: | + helm template test charts/arcadedb/ \ + --set autoscaling.enabled=true \ + --set autoscaling.minReplicas=3 \ + --set autoscaling.maxReplicas=5 > /dev/null + + - name: Template - HPA quorum guard fires + run: | + helm template test charts/arcadedb/ \ + --set autoscaling.enabled=true \ + --set autoscaling.minReplicas=1 \ + --set autoscaling.maxReplicas=5 2>&1 | grep -i "quorum" + + - name: Template - ingress enabled + run: | + helm template test charts/arcadedb/ \ + --set ingress.enabled=true > /dev/null + + - name: Template - NetworkPolicy enabled + run: | + helm template test charts/arcadedb/ \ + --set networkPolicy.enabled=true > /dev/null +``` + +- [ ] **Step 2: Commit and push** + +```bash +git add .github/workflows/lint.yml +git commit -m "ci: add PR lint and template validation workflow" +git push origin main +``` + +- [ ] **Step 3: Verify the workflow ran green** + +```bash +gh run list --workflow=lint.yml --limit=3 +``` + +Expected: latest run shows `completed` with `success` status. If it failed, run `gh run view --log-failed` to diagnose. + +--- + +## Task 4: Create the release workflow + +**Files:** +- Create: `.github/workflows/release.yml` + +- [ ] **Step 1: Create `.github/workflows/release.yml`** + +```yaml +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: "Chart version (e.g. 26.5.2)" + required: true + app_version: + description: "ArcadeDB server version (e.g. 26.5.1) — leave blank to keep current appVersion" + required: false + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Validate version format + run: | + if ! echo "${{ github.event.inputs.version }}" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "Error: '${{ github.event.inputs.version }}' is not valid semver (X.Y.Z)" + exit 1 + fi + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: v3.14.0 + + - name: Update Chart.yaml + run: | + VERSION="${{ github.event.inputs.version }}" + APP_VERSION="${{ github.event.inputs.app_version }}" + sed -i "s/^version:.*/version: ${VERSION}/" charts/arcadedb/Chart.yaml + if [ -n "${APP_VERSION}" ]; then + sed -i "s/^appVersion:.*/appVersion: \"${APP_VERSION}\"/" charts/arcadedb/Chart.yaml + fi + echo "--- Chart.yaml after update ---" + cat charts/arcadedb/Chart.yaml + + - name: Lint + run: helm lint charts/arcadedb/ + + - name: Commit and tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add charts/arcadedb/Chart.yaml + git commit -m "chore(helm): release v${{ github.event.inputs.version }}" + git tag "v${{ github.event.inputs.version }}" + git push origin main --follow-tags + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.6.0 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + with: + charts_dir: charts + skip_existing: true +``` + +- [ ] **Step 2: Commit and push** + +```bash +git add .github/workflows/release.yml +git commit -m "ci: add manual-dispatch release workflow" +git push origin main +``` + +- [ ] **Step 3: Verify the workflow appears in GitHub Actions** + +```bash +gh workflow list +``` + +Expected: both `Lint` and `Release` appear in the output. + +--- + +## Task 5: Run first release and enable GitHub Pages + +**Context:** `helm/chart-releaser-action` automatically creates and pushes to a `gh-pages` branch on the first run. After the branch exists, GitHub Pages must be manually enabled in the repo settings (one-time only). The stable URL will be `https://arcadedata.github.io/arcadedb-helm/`. + +- [ ] **Step 1: Trigger the release workflow** + +```bash +gh workflow run release.yml \ + --field version=26.5.1 \ + --field app_version=26.5.1 +``` + +- [ ] **Step 2: Wait for the workflow to complete** + +```bash +gh run watch $(gh run list --workflow=release.yml --limit=1 --json databaseId --jq '.[0].databaseId') +``` + +Expected: workflow completes with `success`. If it fails, check logs: +```bash +gh run view --log-failed +``` + +- [ ] **Step 3: Verify GitHub Release was created** + +```bash +gh release list +``` + +Expected: `v26.5.1` release appears with a `arcadedb-26.5.1.tgz` asset. + +- [ ] **Step 4: Enable GitHub Pages on the `gh-pages` branch** + +Navigate to: `https://github.com/ArcadeData/arcadedb-helm/settings/pages` + +Set: +- Source: `Deploy from a branch` +- Branch: `gh-pages` +- Folder: `/ (root)` + +Click **Save**. GitHub Pages deployment takes 1-2 minutes. + +- [ ] **Step 5: Verify GitHub Pages is serving index.yaml** + +```bash +curl -s https://arcadedata.github.io/arcadedb-helm/index.yaml | head -5 +``` + +Expected output: +```yaml +apiVersion: v1 +entries: + arcadedb: + - apiVersion: v2 + appVersion: 26.5.1 +``` + +- [ ] **Step 6: Verify helm repo add and install work end-to-end** + +```bash +helm repo add arcadedb-test https://arcadedata.github.io/arcadedb-helm/ +helm repo update +helm search repo arcadedb-test +helm install dry-run-test arcadedb-test/arcadedb --dry-run --generate-name 2>&1 | grep "NAME:" +helm repo remove arcadedb-test +``` + +Expected: `helm search repo` shows `arcadedb-test/arcadedb` at version `26.5.1`. `helm install --dry-run` outputs a line starting with `NAME:`. + +--- + +## Task 6: Register on Artifact Hub and add ownership annotation + +**Context:** Artifact Hub registration requires the `index.yaml` to be publicly accessible (done in Task 5). The `repositoryID` UUID is assigned by Artifact Hub and proves ownership. It must be added to `Chart.yaml` so Artifact Hub can verify it when indexing. + +- [ ] **Step 1: Register the repository on Artifact Hub** + +1. Go to [https://artifacthub.io](https://artifacthub.io) and sign in (or create an account) +2. Click your avatar → **Control Panel** → **Add repository** +3. Fill in: + - Kind: `Helm charts` + - Name: `arcadedb` + - Display name: `ArcadeDB` + - URL: `https://arcadedata.github.io/arcadedb-helm/` +4. Click **Add** +5. Copy the `repositoryID` UUID shown (format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) + +- [ ] **Step 2: Add the ownership annotation to `charts/arcadedb/Chart.yaml`** + +Add this block after `appVersion` in `charts/arcadedb/Chart.yaml` (replace the UUID with the one copied in Step 1): + +```yaml +annotations: + artifacthub.io/repositoryID: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +``` + +The full `Chart.yaml` should now look like: + +```yaml +apiVersion: v2 +name: arcadedb +description: | + A Helm chart for ArcadeDB + +type: application + +version: 26.5.1 + +appVersion: "26.5.1" + +annotations: + artifacthub.io/repositoryID: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +``` + +- [ ] **Step 3: Commit the annotation (no release needed - Artifact Hub picks it up on next release)** + +```bash +git add charts/arcadedb/Chart.yaml +git commit -m "chore: add Artifact Hub repository ownership annotation" +git push origin main +``` + +- [ ] **Step 4: Verify Artifact Hub indexes the chart** + +Wait 5-10 minutes, then: + +```bash +helm search hub arcadedb 2>/dev/null | grep arcadedb-helm || \ + echo "Not yet indexed - check https://artifacthub.io/packages/search?q=arcadedb" +``` + +The chart page will be live at: `https://artifacthub.io/packages/helm/arcadedb/arcadedb` + +--- + +## Task 7: Clean up the main arcadedb repo + +**Context:** Switch back to the `arcadedb` monorepo for this task. The goal is to remove `k8s/helm/` and leave a clear redirect. Also close issue #4034 now that the chart has a proper home. + +**Files (in `ArcadeData/arcadedb` monorepo):** +- Delete: `k8s/helm/` (entire directory) +- Create: `k8s/README.md` + +- [ ] **Step 1: Delete the helm directory** + +```bash +# From inside the arcadedb monorepo root +git rm -r k8s/helm/ +``` + +Expected: all `k8s/helm/` files staged for deletion. + +- [ ] **Step 2: Create `k8s/README.md`** + +```markdown +# Kubernetes + +The ArcadeDB Helm chart has moved to its own repository: + +**https://github.com/ArcadeData/arcadedb-helm** + +## Install + +```bash +helm repo add arcadedb https://arcadedata.github.io/arcadedb-helm/ +helm repo update +helm install my-arcadedb arcadedb/arcadedb +``` +``` + +- [ ] **Step 3: Commit and push** + +```bash +git add k8s/README.md +git commit -m "chore: remove k8s/helm/ - chart moved to ArcadeData/arcadedb-helm" +git push origin main +``` + +- [ ] **Step 4: Close issue #4034 with a pointer to the new repo** + +```bash +gh issue comment 4034 \ + --repo ArcadeData/arcadedb \ + --body "The Helm chart refactored in this issue has been moved to its permanent home at https://github.com/ArcadeData/arcadedb-helm. Install via: + +\`\`\`bash +helm repo add arcadedb https://arcadedata.github.io/arcadedb-helm/ +helm repo update +helm install my-arcadedb arcadedb/arcadedb +\`\`\`" + +gh issue close 4034 --repo ArcadeData/arcadedb --reason completed +``` + +Expected: issue #4034 is closed with the comment visible. From 1ce68f2cc5b902f777f325a0465fdbbf79336cc3 Mon Sep 17 00:00:00 2001 From: robfrank Date: Thu, 30 Apr 2026 11:12:35 +0200 Subject: [PATCH 7/7] chore: remove k8s/helm/ - chart moved to ArcadeData/arcadedb-helm --- k8s/README.md | 13 ++ k8s/helm/Chart.yaml | 10 - k8s/helm/README.md | 228 ----------------------- k8s/helm/index.yaml | 3 - k8s/helm/templates/NOTES.txt | 27 --- k8s/helm/templates/_helpers.tpl | 171 ----------------- k8s/helm/templates/extra-manifests.yaml | 12 -- k8s/helm/templates/hpa.yaml | 40 ---- k8s/helm/templates/ingress.yaml | 43 ----- k8s/helm/templates/networkpolicy.yaml | 39 ---- k8s/helm/templates/secret.yaml | 13 -- k8s/helm/templates/service.yaml | 44 ----- k8s/helm/templates/serviceaccount.yaml | 13 -- k8s/helm/templates/statefulset.yaml | 146 --------------- k8s/helm/values.yaml | 237 ------------------------ 15 files changed, 13 insertions(+), 1026 deletions(-) create mode 100644 k8s/README.md delete mode 100644 k8s/helm/Chart.yaml delete mode 100644 k8s/helm/README.md delete mode 100644 k8s/helm/index.yaml delete mode 100644 k8s/helm/templates/NOTES.txt delete mode 100644 k8s/helm/templates/_helpers.tpl delete mode 100644 k8s/helm/templates/extra-manifests.yaml delete mode 100644 k8s/helm/templates/hpa.yaml delete mode 100644 k8s/helm/templates/ingress.yaml delete mode 100644 k8s/helm/templates/networkpolicy.yaml delete mode 100644 k8s/helm/templates/secret.yaml delete mode 100644 k8s/helm/templates/service.yaml delete mode 100644 k8s/helm/templates/serviceaccount.yaml delete mode 100644 k8s/helm/templates/statefulset.yaml delete mode 100644 k8s/helm/values.yaml diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 0000000000..951e62f900 --- /dev/null +++ b/k8s/README.md @@ -0,0 +1,13 @@ +# Kubernetes + +The ArcadeDB Helm chart has moved to its own repository: + +**https://github.com/ArcadeData/arcadedb-helm** + +## Install + +```bash +helm repo add arcadedb https://helm.arcadedb.com/ +helm repo update +helm install my-arcadedb arcadedb/arcadedb +``` diff --git a/k8s/helm/Chart.yaml b/k8s/helm/Chart.yaml deleted file mode 100644 index 2027be0c62..0000000000 --- a/k8s/helm/Chart.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v2 -name: arcadedb -description: | - A Helm chart for ArcadeDB - -type: application - -version: 26.5.1 - -appVersion: "26.5.1" diff --git a/k8s/helm/README.md b/k8s/helm/README.md deleted file mode 100644 index d65768a8aa..0000000000 --- a/k8s/helm/README.md +++ /dev/null @@ -1,228 +0,0 @@ -# ArcadeDB Helm Chart - -This Helm chart facilitates the deployment of [ArcadeDB](https://arcadedb.com/), an open-source multi-model database, on a -Kubernetes cluster. - -## Prerequisites - -- Kubernetes 1.19+ -- Helm 3.0+ - -## Installation - -To install the chart with the release name `my-arcadedb`: - -```bash -helm install my-arcadedb ./arcadedb -``` - -The command deploys ArcadeDB on the Kubernetes cluster using the default configuration. The [Parameters](#parameters) section lists -the configurable parameters of this chart and their default values. - -## Uninstallation - -To uninstall/delete the `my-arcadedb` deployment: - -```bash -helm uninstall my-arcadedb -``` - -The command removes all the Kubernetes components associated with the chart and deletes the release. - -## Parameters - -### arcadedb - -| Name | Description | Value | -|------------------------------|--------------------------------------------------------------------|------------------------------------------| -| `arcadedb.databaseDirectory` | Database storage directory inside the container | `/home/arcadedb/databases` | -| `arcadedb.defaultDatabases` | Databases to create at startup. Empty = none. | `""` | -| `arcadedb.extraCommands` | Extra JVM -D arguments appended to the startup command | `["-Darcadedb.server.mode=production"]` | -| `arcadedb.extraEnvironment` | Additional environment variables to pass to the ArcadeDB container | `[]` | - -### arcadedb.credentials - -### arcadedb.credentials.rootPassword - -### arcadedb.credentials.secret - -| Name | Description | Value | -|-------------------------------------------------|-------------------------------|-------| -| `arcadedb.credentials.rootPassword.secret.name` | Name of existing secret | `nil` | -| `arcadedb.credentials.rootPassword.secret.key` | Key to use in existing secret | `nil` | - -### image - -| Name | Description | Value | -|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------| -| `image.registry` | Registry for image | `arcadedata` | -| `image.repository` | Image repo | `arcadedb` | -| `image.pullPolicy` | This sets the pull policy for images. | `IfNotPresent` | -| `image.tag` | Overrides the image tag whose default is the chart appVersion. | `""` | -| `imagePullSecrets` | This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | `[]` | -| `nameOverride` | This is to override the chart name. | `""` | -| `fullnameOverride` | | `""` | - -### This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ - -| Name | Description | Value | -|------------------------------|---------------------------------------------------------|--------| -| `serviceAccount.create` | Specifies whether a service account should be created | `true` | -| `serviceAccount.automount` | Mount the ServiceAccount token into pods. ArcadeDB does not call the Kubernetes API - keep false. | `false` | -| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | -| `serviceAccount.name` | The name of the service account to use. | `""` | -| `podAnnotations` | Annotations added to every pod. | `{}` | -| `podLabels` | Labels added to every pod. | `{}` | -| `podSecurityContext` | Pod-level security context. UID/GID 1000 matches the arcadedb user in the Docker image. | `{runAsNonRoot: true, fsGroup: 1000}` | -| `securityContext` | Container-level security context. | `{runAsUser: 1000, runAsGroup: 1000, allowPrivilegeEscalation: false, capabilities.drop: [ALL]}` | - -### This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ - -### http - -| Name | Description | Value | -|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------| -| `service.http.type` | Service type. Use LoadBalancer or configure ingress for external access. | `ClusterIP` | -| `service.http.port` | This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports | `2480` | - -### rpc - -| Name | Description | Value | -|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------| -| `service.rpc.port` | Raft gRPC port (ha-raft subsystem). | `2434` | - -### ingress This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ - -| Name | Description | Value | -|-----------------------|-------------|---------| -| `ingress.enabled` | | `false` | -| `ingress.className` | | `""` | -| `ingress.annotations` | | `{}` | - -### ingress.hosts - -| Name | Description | Value | -|-------------------------|-------------|-----------------------| -| `ingress.hosts[0].host` | | `chart-example.local` | - -### ingress.hosts[0].paths - -| Name | Description | Value | -|--------------------------------------|-------------|--------------------------| -| `ingress.hosts[0].paths[0].path` | | `/` | -| `ingress.hosts[0].paths[0].pathType` | | `ImplementationSpecific` | -| `ingress.tls` | | `[]` | -| `resources` | | `{}` | - -### This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ - -### livenessProbe.httpGet - -| Name | Description | Value | -|------------------------------|-------------|-----------------| -| `livenessProbe.httpGet.path` | | `/api/v1/ready` | -| `livenessProbe.httpGet.port` | | `http` | - -### This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ - -### readinessProbe.httpGet - -| Name | Description | Value | -|-------------------------------|-------------|-----------------| -| `readinessProbe.httpGet.path` | | `/api/v1/ready` | -| `readinessProbe.httpGet.port` | | `http` | - -### This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ - -| Name | Description | Value | -|----------------------------------------------|-----------------------------------------------------------------------|---------| -| `autoscaling.enabled` | Enable HorizontalPodAutoscaler. When enabled, server list is pre-sized to maxReplicas for KubernetesAutoJoin. | `false` | -| `autoscaling.minReplicas` | Minimum replicas. Must satisfy Raft quorum when HA is active: >= floor(maxReplicas/2)+1. | `1` | -| `autoscaling.maxReplicas` | Maximum replicas. Chart enforces quorum guard at render time. | `5` | -| `autoscaling.targetCPUUtilizationPercentage` | | `80` | -| `volumes` | Additional volumes on the output StatefulSet definition. | `[]` | -| `volumeMounts` | Additional volumeMounts on the output StatefulSet definition. | `[]` | -| `volumeClaimTemplates` | Extra StatefulSet volumeClaimTemplates (the database PVC is controlled by `persistence.enabled`). | `[]` | - -### persistence - -| Name | Description | Value | -|----------------------------|-----------------------------------------------------------------------------------------------------|-----------------| -| `persistence.enabled` | Persist the database directory with a PVC. Set false only for ephemeral/dev deployments. | `true` | -| `persistence.size` | PVC size. | `8Gi` | -| `persistence.accessMode` | PVC access mode. | `ReadWriteOnce` | -| `persistence.storageClass` | StorageClass name. Empty string uses the cluster default. | `""` | - -### networkPolicy - -| Name | Description | Value | -|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------|---------| -| `networkPolicy.enabled` | Create NetworkPolicy resources. HTTP (2480) open to all cluster pods; Raft gRPC (2434) restricted to ArcadeDB pods only. | `false` | -| `nodeSelector` | | `{}` | -| `tolerations` | | `[]` | - -### affinity - -### Set the anti-affinity selector scope to arcadedb servers. - -### preferredDuringSchedulingIgnoredDuringExecution - -| Name | Description | Value | -|--------------------------------------------------------------------------------------|---------------------------------------------------|-------| -| `affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].weight` | | `100` | -| `extraManifests` | - Include any amount of extra arbitrary manifests | `{}` | - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example: - -```bash -helm install my-arcadedb ./arcadedb --set image.tag=21.11.1 -``` - -Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example: - -```bash -helm install my-arcadedb ./arcadedb -f values.yaml -``` - -## Persistence - -The ArcadeDB image stores data at `/home/arcadedb/databases` inside the container. By default (`persistence.enabled: true`), a -PersistentVolumeClaim named `arcadedb-data` is created and mounted at that path. Set `persistence.enabled` to `false` only for -ephemeral or development deployments - data will be written to the container's writable layer and lost when the Pod is deleted. - -## Ingress - -This chart provides support for Ingress resource. To enable Ingress, set `ingress.enabled` to `true` and configure the -`ingress.hosts` parameter. For example: - -```yaml -ingress: - enabled: true - hosts: - - host: arcadedb.local - paths: [ ] -``` - -## Resources - -Resource requests and limits are unset by default for dev/Minikube compatibility. For production, set them via: - -```yaml -resources: - requests: - cpu: 500m - memory: 2Gi # matches -Xms2G set by ARCADEDB_OPTS_MEMORY in the Docker image - limits: - memory: 4Gi # no CPU limit - avoids throttling JVM GC pauses -``` - -## Notes - -After installing the chart, you can access ArcadeDB by running the following command: - -```bash -kubectl get --namespace default service arcadedb-http -``` - -Replace `arcadedb-http` with your release name if it's different. The command retrieves the service details, including the IP -address and port, which you can use to connect to ArcadeDB. diff --git a/k8s/helm/index.yaml b/k8s/helm/index.yaml deleted file mode 100644 index 2b50a545df..0000000000 --- a/k8s/helm/index.yaml +++ /dev/null @@ -1,3 +0,0 @@ -apiVersion: v1 -entries: {} -generated: "2025-03-03T07:54:53.678656559+01:00" diff --git a/k8s/helm/templates/NOTES.txt b/k8s/helm/templates/NOTES.txt deleted file mode 100644 index 6c89cee459..0000000000 --- a/k8s/helm/templates/NOTES.txt +++ /dev/null @@ -1,27 +0,0 @@ -1. Get the application URL by running these commands: -{{- if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.http.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "arcadedb.fullname" . }}-http) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.http.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "arcadedb.fullname" . }}-http' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "arcadedb.fullname" . }}-http --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.http.port }} -{{- else if contains "ClusterIP" .Values.service.http.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "arcadedb.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} -{{- if not .Values.persistence.enabled }} - -WARNING: persistence.enabled is false. Database data is EPHEMERAL and will be lost when pods restart. - Set persistence.enabled=true (the default) for any non-ephemeral deployment. -{{- end }} diff --git a/k8s/helm/templates/_helpers.tpl b/k8s/helm/templates/_helpers.tpl deleted file mode 100644 index 211a74f6df..0000000000 --- a/k8s/helm/templates/_helpers.tpl +++ /dev/null @@ -1,171 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "arcadedb.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "arcadedb.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "arcadedb.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "arcadedb.labels" -}} -app: {{ .Chart.Name }} -helm.sh/chart: {{ include "arcadedb.chart" . }} -{{ include "arcadedb.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "arcadedb.selectorLabels" -}} -app.kubernetes.io/name: {{ include "arcadedb.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "arcadedb.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "arcadedb.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} - -{{/* - Creates kubernetes naming suffix. -*/}} -{{- define "arcadedb.k8sSuffix" -}} -{{- $fullname := (include "arcadedb.fullname" .) -}} -{{- printf ".%s.%s.svc.cluster.local" $fullname .Release.Namespace -}} -{{- end }} - -{{/* -Create a comma-separated list of StatefulSet pod FQDNs for the Raft HA server list. -When HPA is enabled, the list is sized to autoscaling.maxReplicas so that -KubernetesAutoJoin can resolve any pod ordinal up to the maximum scale. -*/}} -{{- define "arcadedb.nodenames" -}} -{{- $replicas := int .Values.replicaCount -}} -{{- if and .Values.autoscaling.enabled (gt (int .Values.autoscaling.maxReplicas) $replicas) -}} - {{- $replicas = int .Values.autoscaling.maxReplicas -}} -{{- end -}} -{{- $names := list -}} -{{- $fullname := (include "arcadedb.fullname" .) -}} -{{- $k8sSuffix := (include "arcadedb.k8sSuffix" .) -}} -{{- $rpcPort := int .Values.service.rpc.port -}} -{{- range $i, $_ := until $replicas }} -{{- $names = append $names (printf "%s-%d%s:%d" $fullname $i $k8sSuffix $rpcPort) }} -{{- end }} -{{- join "," $names -}} -{{- end }} - -{{/* -Preparing a list of plugin ports to build plugin configurations. -*/}} -{{- define "_arcadedb.plugin.ports" -}} - {{- range $plugin, $config := .Values.arcadedb.plugins -}} - {{- if $config.enabled }} - {{- $port := int 0}} - {{- if eq $plugin "gremlin" }} - {{- $port = default 8182 $config.port }} - {{- else if eq $plugin "postgres" }} - {{- $port = default 5432 $config.port }} - {{- else if eq $plugin "mongo" }} - {{- $port = default 27017 $config.port }} - {{- else if eq $plugin "redis" }} - {{- $port = default 6379 $config.port }} - {{- else if eq $plugin "prometheus" }} - {{/* - Prometheus does not use a port in the plugin configuration. It is accessible from /prometheus endpoint. - */}} - {{- $port = -1 }} - {{- else }} - {{- if not $config.port }} - {{- fail (printf "Custom plugin '%s' has no port specified." $plugin) -}} - {{- end }} - {{- end }} -{{ $plugin }}: - port: {{ $port }} - class: {{ default "" $config.class }} - {{- end }} - {{- end }} -{{- end }} - -{{/* -Create a comma separated list of plugins to be enabled in arcadedb -*/}} -{{- define "arcadedb.plugin.parameters" -}} -{{- $plugins := list -}} -{{- $params := list -}} - {{- range $plugin, $config := (include "_arcadedb.plugin.ports" . | fromYaml) -}} - {{- if eq $plugin "gremlin" -}} - {{- $plugins = append $plugins "GremlinServer:com.arcadedb.server.gremlin.GremlinServerPlugin" -}} - {{- $params = append $params (printf "-Darcadedb.gremlin.port=%d" (int $config.port)) -}} - {{- else if eq $plugin "postgres" -}} - {{- $plugins = append $plugins "Postgres:com.arcadedb.postgres.PostgresProtocolPlugin" -}} - {{- $params = append $params (printf "-Darcadedb.postgres.port=%d" (int $config.port)) -}} - {{- else if eq $plugin "mongo" -}} - {{- $plugins = append $plugins "MongoDB:com.arcadedb.mongo.MongoDBProtocolPlugin" -}} - {{- $params = append $params (printf "-Darcadedb.mongo.port=%d" (int $config.port)) -}} - {{- else if eq $plugin "redis" -}} - {{- $plugins = append $plugins "Redis:com.arcadedb.redis.RedisProtocolPlugin" -}} - {{- $params = append $params (printf "-Darcadedb.redis.port=%d" (int $config.port)) -}} - {{- else if eq $plugin "prometheus" -}} - {{- $plugins = append $plugins "Prometheus:com.arcadedb.metrics.prometheus.PrometheusMetricsPlugin" -}} - {{- else -}} - {{- $plugins = append $plugins (printf "%s:%s" $plugin $config.class) -}} - {{- end -}} - {{- end -}} -{{- if gt (len $plugins) 0 -}} -- -Darcadedb.server.plugins={{ join "," $plugins }} -{{- end -}} -{{ range $param := $params }} -- {{ $param }} -{{- end -}} -{{- end -}} - -{{/* -Create service configuration for the enabled plugins -*/}} -{{- define "arcadedb.plugin.service" -}} - {{- $plugins := (include "_arcadedb.plugin.ports" . | fromYaml) }} - {{- range $plugin, $config := $plugins }} - {{- if (gt (int $config.port) 0) }} -- port: {{ $config.port }} - targetPort: {{ $config.port }} - protocol: TCP - name: {{ $plugin }}-port - {{- end -}} - {{- end -}} -{{- end -}} diff --git a/k8s/helm/templates/extra-manifests.yaml b/k8s/helm/templates/extra-manifests.yaml deleted file mode 100644 index 5d0f3ed8a6..0000000000 --- a/k8s/helm/templates/extra-manifests.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if .Values.extraManifests }} ---- - -{{- range $_key, $value := .Values.extraManifests }} -{{- with $value }} -{{ toYaml . }} -{{- end }} - ---- - -{{- end }} -{{- end }} diff --git a/k8s/helm/templates/hpa.yaml b/k8s/helm/templates/hpa.yaml deleted file mode 100644 index bb0275b7f0..0000000000 --- a/k8s/helm/templates/hpa.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- if .Values.autoscaling.enabled }} -{{- if or (gt (int .Values.replicaCount) 1) .Values.autoscaling.enabled }} -{{- $maxReplicas := int .Values.autoscaling.maxReplicas }} -{{- $minReplicas := int .Values.autoscaling.minReplicas }} -{{- $quorum := add (div $maxReplicas 2) 1 }} -{{- if lt $minReplicas (int $quorum) }} -{{- fail (printf "autoscaling.minReplicas (%d) must be >= floor(maxReplicas/2)+1 (%d) to maintain Raft quorum with maxReplicas=%d. Increase minReplicas or decrease maxReplicas." $minReplicas (int $quorum) $maxReplicas) }} -{{- end }} -{{- end }} -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: {{ include "arcadedb.fullname" . }} - labels: - {{- include "arcadedb.labels" . | nindent 4 }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: StatefulSet - name: {{ include "arcadedb.fullname" . }} - minReplicas: {{ .Values.autoscaling.minReplicas }} - maxReplicas: {{ .Values.autoscaling.maxReplicas }} - metrics: - {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} - {{- end }} - {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - target: - type: Utilization - averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} - {{- end }} -{{- end }} diff --git a/k8s/helm/templates/ingress.yaml b/k8s/helm/templates/ingress.yaml deleted file mode 100644 index 2e5526df08..0000000000 --- a/k8s/helm/templates/ingress.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if .Values.ingress.enabled -}} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ include "arcadedb.fullname" . }} - labels: - {{- include "arcadedb.labels" . | nindent 4 }} - {{- with .Values.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- with .Values.ingress.className }} - ingressClassName: {{ . }} - {{- end }} - {{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} - rules: - {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} - http: - paths: - {{- range .paths }} - - path: {{ .path }} - {{- with .pathType }} - pathType: {{ . }} - {{- end }} - backend: - service: - name: {{ include "arcadedb.fullname" $ }}-http - port: - number: {{ $.Values.service.http.port }} - {{- end }} - {{- end }} -{{- end }} diff --git a/k8s/helm/templates/networkpolicy.yaml b/k8s/helm/templates/networkpolicy.yaml deleted file mode 100644 index 27f5d3360e..0000000000 --- a/k8s/helm/templates/networkpolicy.yaml +++ /dev/null @@ -1,39 +0,0 @@ -{{- if .Values.networkPolicy.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ include "arcadedb.fullname" . }}-http - labels: - {{- include "arcadedb.labels" . | nindent 4 }} -spec: - podSelector: - matchLabels: - {{- include "arcadedb.selectorLabels" . | nindent 6 }} - policyTypes: - - Ingress - ingress: - - ports: - - port: {{ .Values.service.http.port }} - protocol: TCP ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ include "arcadedb.fullname" . }}-raft - labels: - {{- include "arcadedb.labels" . | nindent 4 }} -spec: - podSelector: - matchLabels: - {{- include "arcadedb.selectorLabels" . | nindent 6 }} - policyTypes: - - Ingress - ingress: - - from: - - podSelector: - matchLabels: - {{- include "arcadedb.selectorLabels" . | nindent 14 }} - ports: - - port: {{ .Values.service.rpc.port }} - protocol: TCP -{{- end }} diff --git a/k8s/helm/templates/secret.yaml b/k8s/helm/templates/secret.yaml deleted file mode 100644 index 7d9261f8ad..0000000000 --- a/k8s/helm/templates/secret.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if not .Values.arcadedb.credentials.rootPassword.secret.name }} -{{ $secret := (lookup "v1" "Secret" .Release.Namespace "arcadedb-credentials-secret") | default dict }} -apiVersion: v1 -kind: Secret -metadata: - name: arcadedb-credentials-secret -type: Opaque -data: - # retrieve the secret data using lookup function and when not exists, return an empty dictionary / map as result - {{- $secretData := (get $secret "data") | default dict }} - {{- $rootPassword := (get $secretData "rootPassword") | default (randAlphaNum 32 | b64enc) }} - rootPassword: {{ $rootPassword }} -{{- end }} diff --git a/k8s/helm/templates/service.yaml b/k8s/helm/templates/service.yaml deleted file mode 100644 index aa9b7a4868..0000000000 --- a/k8s/helm/templates/service.yaml +++ /dev/null @@ -1,44 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "arcadedb.fullname" . }}-http - labels: - {{- include "arcadedb.labels" . | nindent 4 }} -spec: - type: {{ .Values.service.http.type }} - ports: - - port: {{ .Values.service.http.port }} - targetPort: http - protocol: TCP - name: http - selector: - {{- include "arcadedb.selectorLabels" . | nindent 4 }} - ---- - -{{/* -Headless service for StatefulSet pod DNS discovery. -publishNotReadyAddresses: true ensures DNS entries exist during bootstrap -before readiness probes pass - required to avoid HA bootstrap deadlock. -*/}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "arcadedb.fullname" . }} - labels: - {{- include "arcadedb.labels" . | nindent 4 }} -spec: - clusterIP: None - publishNotReadyAddresses: true - ports: - - port: {{ .Values.service.http.port }} - targetPort: http - protocol: TCP - name: http - - port: {{ .Values.service.rpc.port }} - targetPort: rpc - protocol: TCP - name: rpc - {{- include "arcadedb.plugin.service" . | nindent 4 }} - selector: - {{- include "arcadedb.selectorLabels" . | nindent 4 }} diff --git a/k8s/helm/templates/serviceaccount.yaml b/k8s/helm/templates/serviceaccount.yaml deleted file mode 100644 index 1abaf59d4c..0000000000 --- a/k8s/helm/templates/serviceaccount.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "arcadedb.serviceAccountName" . }} - labels: - {{- include "arcadedb.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -automountServiceAccountToken: {{ .Values.serviceAccount.automount }} -{{- end }} diff --git a/k8s/helm/templates/statefulset.yaml b/k8s/helm/templates/statefulset.yaml deleted file mode 100644 index 8817e63c16..0000000000 --- a/k8s/helm/templates/statefulset.yaml +++ /dev/null @@ -1,146 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "arcadedb.fullname" . }} - labels: - {{- include "arcadedb.labels" . | nindent 4 }} -spec: - serviceName: {{ include "arcadedb.fullname" . }} - {{- if not .Values.autoscaling.enabled }} - replicas: {{ .Values.replicaCount }} - {{- end }} - selector: - matchLabels: - {{- include "arcadedb.selectorLabels" . | nindent 6 }} - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "arcadedb.labels" . | nindent 8 }} - {{- with .Values.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "arcadedb.serviceAccountName" . }} - {{- with .Values.podSecurityContext }} - securityContext: - {{- toYaml . | nindent 8 }} - {{- end }} - containers: - - name: {{ .Chart.Name }} - {{- with .Values.securityContext }} - securityContext: - {{- toYaml . | nindent 12 }} - {{- end }} - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - ports: - - name: http - containerPort: {{ .Values.service.http.port }} - protocol: TCP - - name: rpc - containerPort: {{ .Values.service.rpc.port }} - protocol: TCP - command: - - bin/server.sh - - -Darcadedb.dumpConfigAtStartup=true - - -Darcadedb.server.name=$(HOSTNAME) - - -Darcadedb.server.rootPassword=$(rootPassword) - - -Darcadedb.server.databaseDirectory={{ .Values.arcadedb.databaseDirectory }} - - -Darcadedb.server.defaultDatabases={{ .Values.arcadedb.defaultDatabases }} - {{- if or (gt (int .Values.replicaCount) 1) .Values.autoscaling.enabled }} - - -Darcadedb.ha.enabled=true - - -Darcadedb.ha.k8s=true - - -Darcadedb.ha.k8sSuffix={{ include "arcadedb.k8sSuffix" . }} - - -Darcadedb.ha.serverList={{ include "arcadedb.nodenames" . }} - - -Darcadedb.ha.raftPort={{ .Values.service.rpc.port }} - {{- end }} - {{- with .Values.arcadedb.extraCommands }} - {{- toYaml . | nindent 12 }} - {{- end }} - {{- include "arcadedb.plugin.parameters" . | nindent 12 }} - {{- with .Values.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - {{- if .Values.persistence.enabled }} - - name: arcadedb-data - mountPath: {{ .Values.arcadedb.databaseDirectory }} - {{- end }} - {{- with .Values.volumeMounts }} - {{- toYaml . | nindent 12 }} - {{- end }} - env: - - name: HOSTNAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_ID - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: rootPassword - {{- if .Values.arcadedb.credentials.rootPassword.secret.name }} - valueFrom: - secretKeyRef: - name: {{ .Values.arcadedb.credentials.rootPassword.secret.name }} - key: {{ .Values.arcadedb.credentials.rootPassword.secret.key }} - optional: false - {{- else }} - valueFrom: - secretKeyRef: - name: arcadedb-credentials-secret - key: rootPassword - {{- end }} - {{- with .Values.arcadedb.extraEnvironment }} - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.volumes }} - volumes: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - volumeClaimTemplates: - {{- if .Values.persistence.enabled }} - - metadata: - name: arcadedb-data - spec: - accessModes: - - {{ .Values.persistence.accessMode }} - {{- if .Values.persistence.storageClass }} - storageClassName: {{ .Values.persistence.storageClass }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size }} - {{- end }} - {{- with .Values.volumeClaimTemplates }} - {{- toYaml . | nindent 4 }} - {{- end }} diff --git a/k8s/helm/values.yaml b/k8s/helm/values.yaml deleted file mode 100644 index 53a27c5884..0000000000 --- a/k8s/helm/values.yaml +++ /dev/null @@ -1,237 +0,0 @@ -## @param replicaCount Number of replicas. Values > 1 enable Raft HA automatically. -replicaCount: 1 - -## @section arcadedb -arcadedb: - ## @param arcadedb.databaseDirectory Database storage directory inside the container - databaseDirectory: "/home/arcadedb/databases" - ## @param arcadedb.defaultDatabases Databases to create at startup. Empty = none. - ## Example: "Universe[admin:password]" - defaultDatabases: "" - ## @param arcadedb.extraCommands Extra JVM -D arguments appended to the startup command - extraCommands: - - -Darcadedb.server.mode=production - ## @param arcadedb.extraEnvironment Additional environment variables for the container - extraEnvironment: [] - - ## @section arcadedb.credentials - credentials: - rootPassword: - ## If secret.name is null a random 32-char secret named 'arcadedb-credentials-secret' is - ## auto-generated. NOTE: helm template (e.g. ArgoCD) regenerates the secret each render. - ## For GitOps workflows supply your own secret and set name + key. - secret: - ## @param arcadedb.credentials.rootPassword.secret.name Existing secret name (null = auto-generate) - name: null - ## @param arcadedb.credentials.rootPassword.secret.key Key inside the existing secret - key: null - - ## @section arcadedb.plugins - ## Uncomment and configure to enable wire-protocol plugins. - plugins: {} - # gremlin: - # enabled: true - # port: 8182 - # postgres: - # enabled: true - # port: 5432 - # mongo: - # enabled: false - # port: 27017 - # redis: - # enabled: false - # port: 6379 - # prometheus: - # enabled: false - ## Custom plugin example: - # myPlugin: - # enabled: true - # port: 1234 - # class: com.example.MyPlugin - -## @section image -image: - ## @param image.registry Container registry - registry: arcadedata - ## @param image.repository Image repository - repository: arcadedb - ## @param image.pullPolicy Image pull policy - pullPolicy: IfNotPresent - ## @param image.tag Image tag. Defaults to chart appVersion. - tag: "" - -## @param imagePullSecrets Secrets for pulling from private registries -imagePullSecrets: [] -## @param nameOverride Override chart name -nameOverride: "" -## @param fullnameOverride Override fully-qualified app name -fullnameOverride: "" - -## @section serviceAccount -serviceAccount: - ## @param serviceAccount.create Create a ServiceAccount - create: true - ## @param serviceAccount.automount Mount the ServiceAccount token into pods. - ## ArcadeDB does not call the Kubernetes API - keep false. - automount: false - ## @param serviceAccount.annotations Annotations for the ServiceAccount - annotations: {} - ## @param serviceAccount.name ServiceAccount name. Auto-generated when empty. - name: "" - -## @param podAnnotations Annotations added to every pod -podAnnotations: {} -## @param podLabels Labels added to every pod -podLabels: {} - -## @param podSecurityContext Pod-level security context. -## UID/GID 1000 matches the 'arcadedb' user created in the Docker image. -podSecurityContext: - runAsNonRoot: true - fsGroup: 1000 - -## @param securityContext Container-level security context -securityContext: - runAsUser: 1000 - runAsGroup: 1000 - allowPrivilegeEscalation: false - capabilities: - drop: [ALL] - -## @section service -service: - ## @section service.http - http: - ## @param service.http.type Service type. Use LoadBalancer or configure ingress for external access. - type: ClusterIP - ## @param service.http.port HTTP / Studio port - port: 2480 - ## @section service.rpc - rpc: - ## @param service.rpc.port Raft gRPC port (new ha-raft subsystem). Was 2424 in old binary-protocol HA. - port: 2434 - -## @section ingress -ingress: - ## @param ingress.enabled Enable Ingress - enabled: false - ## @param ingress.className IngressClass name - className: "" - ## @param ingress.annotations Ingress annotations - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - ## @section ingress.hosts - hosts: - - host: chart-example.local - paths: - - path: / - pathType: ImplementationSpecific - ## @param ingress.tls TLS configuration - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - -## @param resources Resource requests and limits. -## Commented out by default for dev/Minikube compatibility. -## Tune and uncomment for production. -resources: {} -# resources: -# requests: -# cpu: 500m -# memory: 2Gi # matches -Xms2G set by ARCADEDB_OPTS_MEMORY in the Docker image -# limits: -# memory: 4Gi # no CPU limit - avoids throttling JVM GC pauses - -## @section livenessProbe -livenessProbe: - httpGet: - path: /api/v1/ready - port: http - -## @section readinessProbe -readinessProbe: - httpGet: - path: /api/v1/ready - port: http - -## @section autoscaling -autoscaling: - ## @param autoscaling.enabled Enable HorizontalPodAutoscaler. - ## When enabled, the HA server list is pre-sized to maxReplicas so KubernetesAutoJoin - ## can add pods dynamically. minReplicas must satisfy Raft quorum: >= floor(maxReplicas/2)+1. - enabled: false - ## @param autoscaling.minReplicas Minimum replicas. Must satisfy Raft quorum when HA is active. - minReplicas: 1 - ## @param autoscaling.maxReplicas Maximum replicas - maxReplicas: 5 - ## @param autoscaling.targetCPUUtilizationPercentage Target CPU utilization - targetCPUUtilizationPercentage: 80 - # targetMemoryUtilizationPercentage: 80 - -## @section persistence -persistence: - ## @param persistence.enabled Persist the database directory with a PVC. - ## Set to false only for ephemeral/dev deployments - all data is lost on pod restart. - enabled: true - ## @param persistence.size PVC size - size: 8Gi - ## @param persistence.accessMode PVC access mode - accessMode: ReadWriteOnce - ## @param persistence.storageClass StorageClass name. Empty = cluster default. - storageClass: "" - -## @param volumes Additional pod volumes -volumes: [] -# - name: arcadedb-config -# configMap: -# name: my-arcadedb-config - -## @param volumeMounts Additional container volume mounts -volumeMounts: [] -# - name: arcadedb-config -# mountPath: /home/arcadedb/config -# readOnly: true - -## @param volumeClaimTemplates Extra StatefulSet volumeClaimTemplates (for config, replication, backups, log). -## The database-data PVC is controlled by persistence.enabled above. -volumeClaimTemplates: [] -# - metadata: -# name: arcadedb-config -# spec: -# accessModes: -# - ReadWriteOnce -# resources: -# requests: -# storage: 1Gi - -## @param nodeSelector Node selector -nodeSelector: {} - -## @param tolerations Tolerations -tolerations: [] - -## @section affinity -affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - - key: app.kubernetes.io/name - operator: In - values: - - arcadedb - topologyKey: kubernetes.io/hostname - -## @param extraManifests Arbitrary extra Kubernetes manifests to include -extraManifests: {} - -## @section networkPolicy -networkPolicy: - ## @param networkPolicy.enabled Create NetworkPolicy resources. - ## When enabled: HTTP (2480) is open to all cluster pods; Raft gRPC (2434) is restricted - ## to ArcadeDB pods only. Recommended for production multi-tenant clusters. - enabled: false