From e833892345bc4c2b2999c7d1a65e5a63558c9c9e Mon Sep 17 00:00:00 2001 From: Robin Date: Mon, 13 Apr 2026 21:14:01 +0200 Subject: [PATCH 1/3] feat: add CodeZero Helm chart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First ISV partner chart. Converts Code Zero's docker-compose (12 services) to Kubernetes-native Helm chart: IDE profile: - Postgres 16.1 StatefulSet with PVC - Sagittarius Rails web (backend API, health checks) - Sagittarius Rails background (GoodJob worker) - Sagittarius gRPC server - Sculptor (Next.js frontend) - Nginx reverse proxy (routes graphql, grpc, static to backends) Runtime profile (conditional, runtime.enabled): - NATS with JetStream - Aquila (runtime gateway, connects to sagittarius via token) - Taurus (flow execution engine) - Draco REST (HTTP trigger adapter) - Draco Cron (scheduled trigger adapter) Config generator replaced with Helm-rendered ConfigMaps — nginx routing config and sagittarius DB config are templated directly, no Ruby ERB container needed. Images from registry.gitlab.com/code0-tech/packages with -ce/-ee suffix. --- apps/codezero/Chart.yaml | 18 ++ apps/codezero/templates/_helpers.tpl | 78 ++++++++ apps/codezero/templates/configmap-nginx.yaml | 83 ++++++++ .../templates/configmap-sagittarius.yaml | 16 ++ apps/codezero/templates/deployment-nginx.yaml | 44 +++++ .../templates/deployment-postgres.yaml | 77 ++++++++ .../templates/deployment-runtime.yaml | 177 ++++++++++++++++++ .../templates/deployment-sagittarius.yaml | 142 ++++++++++++++ .../templates/deployment-sculptor.yaml | 27 +++ apps/codezero/templates/secret.yaml | 18 ++ apps/codezero/templates/services.yaml | 122 ++++++++++++ apps/codezero/values.yaml | 86 +++++++++ 12 files changed, 888 insertions(+) create mode 100644 apps/codezero/Chart.yaml create mode 100644 apps/codezero/templates/_helpers.tpl create mode 100644 apps/codezero/templates/configmap-nginx.yaml create mode 100644 apps/codezero/templates/configmap-sagittarius.yaml create mode 100644 apps/codezero/templates/deployment-nginx.yaml create mode 100644 apps/codezero/templates/deployment-postgres.yaml create mode 100644 apps/codezero/templates/deployment-runtime.yaml create mode 100644 apps/codezero/templates/deployment-sagittarius.yaml create mode 100644 apps/codezero/templates/deployment-sculptor.yaml create mode 100644 apps/codezero/templates/secret.yaml create mode 100644 apps/codezero/templates/services.yaml create mode 100644 apps/codezero/values.yaml diff --git a/apps/codezero/Chart.yaml b/apps/codezero/Chart.yaml new file mode 100644 index 0000000..c3cbbec --- /dev/null +++ b/apps/codezero/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: codezero +description: CodeZero — no-code workflow automation & AI orchestration platform +type: application +version: 0.1.0 +appVersion: 'canary' +home: https://codezero.build +sources: + - https://github.com/code0-tech/codezero +maintainers: + - name: CNAP Technologies + url: https://cnap.tech +keywords: + - automation + - workflow + - no-code + - ai + - orchestration diff --git a/apps/codezero/templates/_helpers.tpl b/apps/codezero/templates/_helpers.tpl new file mode 100644 index 0000000..d425239 --- /dev/null +++ b/apps/codezero/templates/_helpers.tpl @@ -0,0 +1,78 @@ +{{/* +Common labels +*/}} +{{- define "codezero.labels" -}} +app.kubernetes.io/name: {{ .Chart.Name }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Values.image.tag | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "codezero.selectorLabels" -}} +app.kubernetes.io/name: {{ .Chart.Name }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Full image reference for Code Zero components +*/}} +{{- define "codezero.image" -}} +{{ .Values.image.registry }}/{{ .component }}:{{ .Values.image.tag }}{{ if .edition }}-{{ .edition }}{{ end }} +{{- end }} + +{{/* +Sagittarius image (includes edition suffix) +*/}} +{{- define "codezero.sagittariusImage" -}} +{{ .Values.image.registry }}/sagittarius:{{ .Values.image.tag }}-{{ .Values.image.edition }} +{{- end }} + +{{/* +Sculptor image (includes edition suffix) +*/}} +{{- define "codezero.sculptorImage" -}} +{{ .Values.image.registry }}/sculptor:{{ .Values.image.tag }}-{{ .Values.image.edition }} +{{- end }} + +{{/* +Component image (no edition suffix) +*/}} +{{- define "codezero.componentImage" -}} +{{ .Values.image.registry }}/{{ .component }}:{{ .Values.image.tag }} +{{- end }} + +{{/* +Draco image with variant suffix +*/}} +{{- define "codezero.dracoImage" -}} +{{ .Values.image.registry }}/draco:{{ .Values.image.tag }}-{{ .variant }} +{{- end }} + +{{/* +Service account name +*/}} +{{- define "codezero.serviceAccountName" -}} +{{- if .Values.serviceAccount.name }} +{{- .Values.serviceAccount.name }} +{{- else }} +{{- .Release.Name }}-codezero +{{- end }} +{{- end }} + +{{/* +Config volume name +*/}} +{{- define "codezero.configVolume" -}} +{{ .Release.Name }}-generated-configs +{{- end }} + +{{/* +Postgres connection details +*/}} +{{- define "codezero.postgresHost" -}} +{{ .Release.Name }}-postgres +{{- end }} diff --git a/apps/codezero/templates/configmap-nginx.yaml b/apps/codezero/templates/configmap-nginx.yaml new file mode 100644 index 0000000..f0eaaec --- /dev/null +++ b/apps/codezero/templates/configmap-nginx.yaml @@ -0,0 +1,83 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-nginx-config + labels: + {{- include "codezero.labels" . | nindent 4 }} +data: + default.conf: | + upstream sagittarius_rails_web { + server {{ .Release.Name }}-sagittarius-web:3000; + } + + upstream sagittarius_grpc { + server {{ .Release.Name }}-sagittarius-grpc:50051; + } + + upstream sculptor { + server {{ .Release.Name }}-sculptor:3000; + } + + server { + listen 80 http2; + server_name _; + + location = /graphql { + proxy_pass http://sagittarius_rails_web; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = /files/upload { + proxy_pass http://sagittarius_rails_web; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + client_max_body_size 100M; + } + + location = /health/liveness { + proxy_pass http://sagittarius_rails_web; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /good_job { + proxy_pass http://sagittarius_rails_web; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = /error502grpc { + internal; + default_type application/grpc; + add_header grpc-status 14; + add_header grpc-message "unavailable"; + return 204; + } + + location / { + if ($content_type = "application/grpc") { + grpc_pass grpc://sagittarius_grpc; + error_page 502 = /error502grpc; + } + grpc_set_header X-Real-IP $remote_addr; + grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + grpc_read_timeout 1h; + grpc_send_timeout 1h; + grpc_socket_keepalive on; + + proxy_pass http://sculptor; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } diff --git a/apps/codezero/templates/configmap-sagittarius.yaml b/apps/codezero/templates/configmap-sagittarius.yaml new file mode 100644 index 0000000..add74bc --- /dev/null +++ b/apps/codezero/templates/configmap-sagittarius.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-sagittarius-config + labels: + {{- include "codezero.labels" . | nindent 4 }} +data: + sagittarius.yml: | + rails: + web: + force_ssl: false + log_level: info + threads: 3 + db: + host: {{ include "codezero.postgresHost" . }} + port: "5432" diff --git a/apps/codezero/templates/deployment-nginx.yaml b/apps/codezero/templates/deployment-nginx.yaml new file mode 100644 index 0000000..6bd0944 --- /dev/null +++ b/apps/codezero/templates/deployment-nginx.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-nginx + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: nginx +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: nginx + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: nginx + spec: + containers: + - name: nginx + image: {{ .Values.nginx.image }} + ports: + - name: http + containerPort: 80 + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d + livenessProbe: + httpGet: + path: /health/liveness + port: 80 + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health/liveness + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: nginx-config + configMap: + name: {{ .Release.Name }}-nginx-config diff --git a/apps/codezero/templates/deployment-postgres.yaml b/apps/codezero/templates/deployment-postgres.yaml new file mode 100644 index 0000000..f018340 --- /dev/null +++ b/apps/codezero/templates/deployment-postgres.yaml @@ -0,0 +1,77 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Release.Name }}-postgres + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: postgres +spec: + serviceName: {{ .Release.Name }}-postgres + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: postgres + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: postgres + spec: + containers: + - name: postgres + image: {{ .Values.postgres.image }} + ports: + - containerPort: 5432 + env: + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-codezero + key: POSTGRES_DB + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-codezero + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-codezero + key: POSTGRES_PASSWORD + volumeMounts: + - name: postgres-data + mountPath: /var/lib/postgresql/data + livenessProbe: + exec: + command: + - pg_isready + - -U + - {{ .Values.postgres.user }} + - -d + - {{ .Values.postgres.database }} + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + exec: + command: + - pg_isready + - -U + - {{ .Values.postgres.user }} + - -d + - {{ .Values.postgres.database }} + initialDelaySeconds: 5 + periodSeconds: 5 + resources: + {{- toYaml .Values.resources.postgres | nindent 12 }} + volumeClaimTemplates: + - metadata: + name: postgres-data + spec: + accessModes: ["ReadWriteOnce"] + {{- if .Values.postgres.storage.storageClassName }} + storageClassName: {{ .Values.postgres.storage.storageClassName }} + {{- end }} + resources: + requests: + storage: {{ .Values.postgres.storage.size }} diff --git a/apps/codezero/templates/deployment-runtime.yaml b/apps/codezero/templates/deployment-runtime.yaml new file mode 100644 index 0000000..c426a04 --- /dev/null +++ b/apps/codezero/templates/deployment-runtime.yaml @@ -0,0 +1,177 @@ +{{- if .Values.runtime.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-nats + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: nats +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: nats + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: nats + spec: + containers: + - name: nats + image: {{ .Values.nats.image }} + args: ["-js"] + ports: + - containerPort: 4222 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-aquila + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: aquila +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: aquila + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: aquila + spec: + containers: + - name: aquila + image: {{ .Values.image.registry }}/aquila:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: MODE + value: dynamic + - name: NATS_URL + value: nats://{{ .Release.Name }}-nats:4222 + - name: NATS_BUCKET + value: flow_store + - name: GRPC_HOST + value: "0.0.0.0" + - name: SAGITTARIUS_URL + value: {{ .Values.runtime.aquila.sagittariusUrl | default (printf "http://%s-nginx:80" .Release.Name) }} + - name: RUNTIME_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-codezero + key: AQUILA_SAGITTARIUS_TOKEN +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-taurus + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: taurus +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: taurus + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: taurus + spec: + containers: + - name: taurus + image: {{ .Values.image.registry }}/taurus:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: MODE + value: dynamic + - name: AQUILA_URL + value: http://{{ .Release.Name }}-aquila:8081 + - name: NATS_URL + value: nats://{{ .Release.Name }}-nats:4222 + - name: DEFINITION_PATH + value: /definitions +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-draco-rest + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: draco-rest +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: draco-rest + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: draco-rest + spec: + containers: + - name: draco-rest + image: {{ .Values.image.registry }}/draco:{{ .Values.image.tag }}-rest + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.runtime.draco.rest.port }} + env: + - name: MODE + value: dynamic + - name: AQUILA_URL + value: http://{{ .Release.Name }}-aquila:8081 + - name: NATS_URL + value: nats://{{ .Release.Name }}-nats:4222 + - name: NATS_BUCKET + value: flow_store + - name: DEFINITION_PATH + value: /definitions + - name: HTTP_SERVER_PORT + value: {{ .Values.runtime.draco.rest.port | quote }} + - name: HTTP_SERVER_HOST + value: "0.0.0.0" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-draco-cron + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: draco-cron +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: draco-cron + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: draco-cron + spec: + containers: + - name: draco-cron + image: {{ .Values.image.registry }}/draco:{{ .Values.image.tag }}-cron + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: MODE + value: dynamic + - name: AQUILA_URL + value: http://{{ .Release.Name }}-aquila:8081 + - name: NATS_URL + value: nats://{{ .Release.Name }}-nats:4222 + - name: NATS_BUCKET + value: flow_store + - name: DEFINITION_PATH + value: /definitions +{{- end }} diff --git a/apps/codezero/templates/deployment-sagittarius.yaml b/apps/codezero/templates/deployment-sagittarius.yaml new file mode 100644 index 0000000..103d966 --- /dev/null +++ b/apps/codezero/templates/deployment-sagittarius.yaml @@ -0,0 +1,142 @@ +{{- $sagittariusImage := include "codezero.sagittariusImage" . -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-sagittarius-web + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: sagittarius-web +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: sagittarius-web + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: sagittarius-web + spec: + containers: + - name: sagittarius-web + image: {{ $sagittariusImage }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh", "-c"] + args: + - | + cp /tmp/config/sagittarius.yml config/sagittarius.yml + exec bin/docker-entrypoint ./bin/rails server + ports: + - containerPort: 3000 + env: + - name: INITIAL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-codezero + key: INITIAL_ROOT_PASSWORD + - name: INITIAL_ROOT_MAIL + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-codezero + key: INITIAL_ROOT_MAIL + volumeMounts: + - name: sagittarius-config + mountPath: /tmp/config + livenessProbe: + httpGet: + path: /health/liveness + port: 3000 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health/liveness + port: 3000 + initialDelaySeconds: 10 + periodSeconds: 5 + resources: + {{- toYaml .Values.resources.sagittarius | nindent 12 }} + volumes: + - name: sagittarius-config + configMap: + name: {{ .Release.Name }}-sagittarius-config +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-sagittarius-background + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: sagittarius-background +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: sagittarius-background + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: sagittarius-background + spec: + containers: + - name: sagittarius-background + image: {{ $sagittariusImage }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh", "-c"] + args: + - | + cp /tmp/config/sagittarius.yml config/sagittarius.yml + exec bin/docker-entrypoint bundle exec good_job + volumeMounts: + - name: sagittarius-config + mountPath: /tmp/config + resources: + {{- toYaml .Values.resources.sagittarius | nindent 12 }} + volumes: + - name: sagittarius-config + configMap: + name: {{ .Release.Name }}-sagittarius-config +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-sagittarius-grpc + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: sagittarius-grpc +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: sagittarius-grpc + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: sagittarius-grpc + spec: + containers: + - name: sagittarius-grpc + image: {{ $sagittariusImage }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh", "-c"] + args: + - | + cp /tmp/config/sagittarius.yml config/sagittarius.yml + exec bin/docker-entrypoint ./bin/grpc_server + ports: + - containerPort: 50051 + volumeMounts: + - name: sagittarius-config + mountPath: /tmp/config + resources: + {{- toYaml .Values.resources.sagittarius | nindent 12 }} + volumes: + - name: sagittarius-config + configMap: + name: {{ .Release.Name }}-sagittarius-config diff --git a/apps/codezero/templates/deployment-sculptor.yaml b/apps/codezero/templates/deployment-sculptor.yaml new file mode 100644 index 0000000..fac2108 --- /dev/null +++ b/apps/codezero/templates/deployment-sculptor.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-sculptor + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: sculptor +spec: + replicas: 1 + selector: + matchLabels: + {{- include "codezero.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: sculptor + template: + metadata: + labels: + {{- include "codezero.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: sculptor + spec: + containers: + - name: sculptor + image: {{ include "codezero.sculptorImage" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 3000 + resources: + {{- toYaml .Values.resources.sculptor | nindent 12 }} diff --git a/apps/codezero/templates/secret.yaml b/apps/codezero/templates/secret.yaml new file mode 100644 index 0000000..acb05b1 --- /dev/null +++ b/apps/codezero/templates/secret.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-codezero + labels: + {{- include "codezero.labels" . | nindent 4 }} +type: Opaque +stringData: + POSTGRES_DB: {{ .Values.postgres.database | quote }} + POSTGRES_USER: {{ .Values.postgres.user | quote }} + POSTGRES_PASSWORD: {{ .Values.postgres.password | quote }} + POSTGRES_HOST: {{ include "codezero.postgresHost" . | quote }} + POSTGRES_PORT: "5432" + INITIAL_ROOT_PASSWORD: {{ .Values.admin.password | quote }} + INITIAL_ROOT_MAIL: {{ .Values.admin.email | quote }} + {{- if .Values.runtime.aquila.sagittariusToken }} + AQUILA_SAGITTARIUS_TOKEN: {{ .Values.runtime.aquila.sagittariusToken | quote }} + {{- end }} diff --git a/apps/codezero/templates/services.yaml b/apps/codezero/templates/services.yaml new file mode 100644 index 0000000..e5c7ff4 --- /dev/null +++ b/apps/codezero/templates/services.yaml @@ -0,0 +1,122 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-postgres + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: postgres +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: postgres + ports: + - port: 5432 + targetPort: 5432 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-sagittarius-web + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: sagittarius-web +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: sagittarius-web + ports: + - port: 3000 + targetPort: 3000 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-sagittarius-grpc + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: sagittarius-grpc +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: sagittarius-grpc + ports: + - port: 50051 + targetPort: 50051 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-sculptor + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: sculptor +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: sculptor + ports: + - port: 3000 + targetPort: 3000 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-nginx + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: nginx +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: nginx + ports: + - name: http + port: 80 + targetPort: 80 +{{- if .Values.runtime.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-nats + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: nats +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: nats + ports: + - port: 4222 + targetPort: 4222 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-aquila + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: aquila +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: aquila + ports: + - port: 8081 + targetPort: 8081 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-draco-rest + labels: + {{- include "codezero.labels" . | nindent 4 }} + app.kubernetes.io/component: draco-rest +spec: + selector: + {{- include "codezero.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: draco-rest + ports: + - port: {{ .Values.runtime.draco.rest.port }} + targetPort: {{ .Values.runtime.draco.rest.port }} +{{- end }} diff --git a/apps/codezero/values.yaml b/apps/codezero/values.yaml new file mode 100644 index 0000000..4441abc --- /dev/null +++ b/apps/codezero/values.yaml @@ -0,0 +1,86 @@ +# CodeZero Helm Chart Values +# https://codezero.build + +# -- Global image settings +image: + registry: registry.gitlab.com/code0-tech/packages + tag: "0.0.0-canary-2356067148-c06e576791513b10dbcb10aa3b0420b87178a205" + edition: "ee" # ce (community) or ee (enterprise) + pullPolicy: IfNotPresent + +# -- Initial admin credentials +admin: + password: "root" + email: "root@code0.tech" + +# -- PostgreSQL +postgres: + image: postgres:16.1 + database: sagittarius_production + user: sagittarius + password: sagittarius + storage: + size: 10Gi + # storageClassName: "" # uses default if not set + +# -- NATS (message broker for runtime) +nats: + image: nats:2.11.9 + +# -- Nginx (reverse proxy) +nginx: + image: nginx:1.29.5-alpine-slim + +# -- HTTP settings +http: + port: 80 + +# -- Runtime settings +runtime: + # -- Enable the runtime profile (workflow execution engine) + enabled: true + # -- Aquila connection to sagittarius + aquila: + sagittariusUrl: "" # auto-configured if empty + sagittariusToken: "" + # -- Draco REST trigger + draco: + rest: + port: 8084 + +# -- Resource defaults +resources: + sagittarius: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 1000m + memory: 1Gi + sculptor: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + postgres: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +# -- Service account +serviceAccount: + create: true + name: "" + +# -- Pod security +podSecurityContext: + fsGroup: 1000 + +securityContext: + runAsNonRoot: true + runAsUser: 1000 From bfd9bede9365862a22235b1b1047798e27317081 Mon Sep 17 00:00:00 2001 From: Robin Date: Mon, 13 Apr 2026 21:19:27 +0200 Subject: [PATCH 2/3] refactor: use Bitnami PostgreSQL as chart dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace inline Postgres StatefulSet with Bitnami postgresql 16.7.5 subchart. Gets us production-grade Postgres with: - Proper StatefulSet + PVC management - Health checks, probes, security context - PodDisruptionBudget, NetworkPolicy, ServiceAccount - Backup support, replication option, metrics exporter - Configurable via standard postgresql.* values Removed: deployment-postgres.yaml, inline postgres Service Added: Chart.yaml dependency, postgresql.* values block Updated: secret, configmap, helpers to reference Bitnami service name NATS kept inline — simple single-instance broker, Bitnami chart would be overkill for Code Zero's use case. --- apps/codezero/Chart.lock | 6 ++ apps/codezero/Chart.yaml | 5 ++ apps/codezero/templates/_helpers.tpl | 4 +- .../templates/configmap-sagittarius.yaml | 2 +- .../templates/deployment-postgres.yaml | 77 ------------------- apps/codezero/templates/secret.yaml | 6 +- apps/codezero/templates/services.yaml | 15 ---- apps/codezero/values.yaml | 34 ++++---- 8 files changed, 36 insertions(+), 113 deletions(-) create mode 100644 apps/codezero/Chart.lock delete mode 100644 apps/codezero/templates/deployment-postgres.yaml diff --git a/apps/codezero/Chart.lock b/apps/codezero/Chart.lock new file mode 100644 index 0000000..743dfcf --- /dev/null +++ b/apps/codezero/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 16.7.5 +digest: sha256:edf5d0f3c2222c358fccfc6dd2316c4bd224bc8cff2fa00d0ea92363f7a260db +generated: "2026-04-13T21:19:04.087651+02:00" diff --git a/apps/codezero/Chart.yaml b/apps/codezero/Chart.yaml index c3cbbec..e6b40e3 100644 --- a/apps/codezero/Chart.yaml +++ b/apps/codezero/Chart.yaml @@ -16,3 +16,8 @@ keywords: - no-code - ai - orchestration +dependencies: + - name: postgresql + version: "16.7.5" + repository: https://charts.bitnami.com/bitnami + condition: postgres.enabled diff --git a/apps/codezero/templates/_helpers.tpl b/apps/codezero/templates/_helpers.tpl index d425239..eeb5264 100644 --- a/apps/codezero/templates/_helpers.tpl +++ b/apps/codezero/templates/_helpers.tpl @@ -71,8 +71,8 @@ Config volume name {{- end }} {{/* -Postgres connection details +Postgres connection details — points to Bitnami subchart service */}} {{- define "codezero.postgresHost" -}} -{{ .Release.Name }}-postgres +{{ .Release.Name }}-postgresql {{- end }} diff --git a/apps/codezero/templates/configmap-sagittarius.yaml b/apps/codezero/templates/configmap-sagittarius.yaml index add74bc..a5f1dbc 100644 --- a/apps/codezero/templates/configmap-sagittarius.yaml +++ b/apps/codezero/templates/configmap-sagittarius.yaml @@ -12,5 +12,5 @@ data: log_level: info threads: 3 db: - host: {{ include "codezero.postgresHost" . }} + host: {{ include "codezero.postgresHost" . | quote }} port: "5432" diff --git a/apps/codezero/templates/deployment-postgres.yaml b/apps/codezero/templates/deployment-postgres.yaml deleted file mode 100644 index f018340..0000000 --- a/apps/codezero/templates/deployment-postgres.yaml +++ /dev/null @@ -1,77 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ .Release.Name }}-postgres - labels: - {{- include "codezero.labels" . | nindent 4 }} - app.kubernetes.io/component: postgres -spec: - serviceName: {{ .Release.Name }}-postgres - replicas: 1 - selector: - matchLabels: - {{- include "codezero.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: postgres - template: - metadata: - labels: - {{- include "codezero.selectorLabels" . | nindent 8 }} - app.kubernetes.io/component: postgres - spec: - containers: - - name: postgres - image: {{ .Values.postgres.image }} - ports: - - containerPort: 5432 - env: - - name: POSTGRES_DB - valueFrom: - secretKeyRef: - name: {{ .Release.Name }}-codezero - key: POSTGRES_DB - - name: POSTGRES_USER - valueFrom: - secretKeyRef: - name: {{ .Release.Name }}-codezero - key: POSTGRES_USER - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: {{ .Release.Name }}-codezero - key: POSTGRES_PASSWORD - volumeMounts: - - name: postgres-data - mountPath: /var/lib/postgresql/data - livenessProbe: - exec: - command: - - pg_isready - - -U - - {{ .Values.postgres.user }} - - -d - - {{ .Values.postgres.database }} - initialDelaySeconds: 10 - periodSeconds: 10 - readinessProbe: - exec: - command: - - pg_isready - - -U - - {{ .Values.postgres.user }} - - -d - - {{ .Values.postgres.database }} - initialDelaySeconds: 5 - periodSeconds: 5 - resources: - {{- toYaml .Values.resources.postgres | nindent 12 }} - volumeClaimTemplates: - - metadata: - name: postgres-data - spec: - accessModes: ["ReadWriteOnce"] - {{- if .Values.postgres.storage.storageClassName }} - storageClassName: {{ .Values.postgres.storage.storageClassName }} - {{- end }} - resources: - requests: - storage: {{ .Values.postgres.storage.size }} diff --git a/apps/codezero/templates/secret.yaml b/apps/codezero/templates/secret.yaml index acb05b1..f48a62f 100644 --- a/apps/codezero/templates/secret.yaml +++ b/apps/codezero/templates/secret.yaml @@ -6,9 +6,9 @@ metadata: {{- include "codezero.labels" . | nindent 4 }} type: Opaque stringData: - POSTGRES_DB: {{ .Values.postgres.database | quote }} - POSTGRES_USER: {{ .Values.postgres.user | quote }} - POSTGRES_PASSWORD: {{ .Values.postgres.password | quote }} + POSTGRES_DB: {{ .Values.postgresql.auth.database | quote }} + POSTGRES_USER: {{ .Values.postgresql.auth.username | quote }} + POSTGRES_PASSWORD: {{ .Values.postgresql.auth.password | quote }} POSTGRES_HOST: {{ include "codezero.postgresHost" . | quote }} POSTGRES_PORT: "5432" INITIAL_ROOT_PASSWORD: {{ .Values.admin.password | quote }} diff --git a/apps/codezero/templates/services.yaml b/apps/codezero/templates/services.yaml index e5c7ff4..724281e 100644 --- a/apps/codezero/templates/services.yaml +++ b/apps/codezero/templates/services.yaml @@ -1,20 +1,5 @@ apiVersion: v1 kind: Service -metadata: - name: {{ .Release.Name }}-postgres - labels: - {{- include "codezero.labels" . | nindent 4 }} - app.kubernetes.io/component: postgres -spec: - selector: - {{- include "codezero.selectorLabels" . | nindent 4 }} - app.kubernetes.io/component: postgres - ports: - - port: 5432 - targetPort: 5432 ---- -apiVersion: v1 -kind: Service metadata: name: {{ .Release.Name }}-sagittarius-web labels: diff --git a/apps/codezero/values.yaml b/apps/codezero/values.yaml index 4441abc..6eaa382 100644 --- a/apps/codezero/values.yaml +++ b/apps/codezero/values.yaml @@ -13,15 +13,26 @@ admin: password: "root" email: "root@code0.tech" -# -- PostgreSQL +# -- PostgreSQL (Bitnami subchart) postgres: - image: postgres:16.1 - database: sagittarius_production - user: sagittarius - password: sagittarius - storage: - size: 10Gi - # storageClassName: "" # uses default if not set + enabled: true # set to false to use an external database + +postgresql: + auth: + database: sagittarius_production + username: sagittarius + password: sagittarius + primary: + persistence: + size: 10Gi + # storageClass: "" # uses default if not set + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi # -- NATS (message broker for runtime) nats: @@ -64,13 +75,6 @@ resources: limits: cpu: 500m memory: 512Mi - postgres: - requests: - cpu: 100m - memory: 256Mi - limits: - cpu: 500m - memory: 512Mi # -- Service account serviceAccount: From e187b7a1f13f3995023b66146a70ecf2cea9f733 Mon Sep 17 00:00:00 2001 From: Robin Date: Mon, 13 Apr 2026 21:21:31 +0200 Subject: [PATCH 3/3] fix: upgrade to Bitnami PostgreSQL 18.5.17 + auto-generated passwords MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgraded from 16.7.5 to 18.5.17 (latest, PostgreSQL 18.3) - Removed hardcoded postgres password from values.yaml — Bitnami auto-generates and stores in K8s Secret - All sagittarius containers read POSTGRES_PASSWORD from Bitnami's secret via secretKeyRef - envFrom used for other env vars from codezero secret --- apps/codezero/Chart.lock | 6 ++-- apps/codezero/Chart.yaml | 2 +- .../templates/deployment-sagittarius.yaml | 32 ++++++++++++++----- apps/codezero/templates/secret.yaml | 7 +++- apps/codezero/values.yaml | 4 ++- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/apps/codezero/Chart.lock b/apps/codezero/Chart.lock index 743dfcf..479c3d1 100644 --- a/apps/codezero/Chart.lock +++ b/apps/codezero/Chart.lock @@ -1,6 +1,6 @@ dependencies: - name: postgresql repository: https://charts.bitnami.com/bitnami - version: 16.7.5 -digest: sha256:edf5d0f3c2222c358fccfc6dd2316c4bd224bc8cff2fa00d0ea92363f7a260db -generated: "2026-04-13T21:19:04.087651+02:00" + version: 18.5.17 +digest: sha256:e5b697e6b97321ba0386615a7cf67cb8b2f37ab4e159fad9fb5f6603a6807f6f +generated: "2026-04-13T21:21:16.724184+02:00" diff --git a/apps/codezero/Chart.yaml b/apps/codezero/Chart.yaml index e6b40e3..9152e73 100644 --- a/apps/codezero/Chart.yaml +++ b/apps/codezero/Chart.yaml @@ -18,6 +18,6 @@ keywords: - orchestration dependencies: - name: postgresql - version: "16.7.5" + version: "18.5.17" repository: https://charts.bitnami.com/bitnami condition: postgres.enabled diff --git a/apps/codezero/templates/deployment-sagittarius.yaml b/apps/codezero/templates/deployment-sagittarius.yaml index 103d966..6e3ef18 100644 --- a/apps/codezero/templates/deployment-sagittarius.yaml +++ b/apps/codezero/templates/deployment-sagittarius.yaml @@ -30,17 +30,15 @@ spec: exec bin/docker-entrypoint ./bin/rails server ports: - containerPort: 3000 + envFrom: + - secretRef: + name: {{ .Release.Name }}-codezero env: - - name: INITIAL_ROOT_PASSWORD + - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: - name: {{ .Release.Name }}-codezero - key: INITIAL_ROOT_PASSWORD - - name: INITIAL_ROOT_MAIL - valueFrom: - secretKeyRef: - name: {{ .Release.Name }}-codezero - key: INITIAL_ROOT_MAIL + name: {{ .Release.Name }}-postgresql + key: password volumeMounts: - name: sagittarius-config mountPath: /tmp/config @@ -91,6 +89,15 @@ spec: - | cp /tmp/config/sagittarius.yml config/sagittarius.yml exec bin/docker-entrypoint bundle exec good_job + envFrom: + - secretRef: + name: {{ .Release.Name }}-codezero + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-postgresql + key: password volumeMounts: - name: sagittarius-config mountPath: /tmp/config @@ -124,6 +131,15 @@ spec: - name: sagittarius-grpc image: {{ $sagittariusImage }} imagePullPolicy: {{ .Values.image.pullPolicy }} + envFrom: + - secretRef: + name: {{ .Release.Name }}-codezero + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-postgresql + key: password command: ["sh", "-c"] args: - | diff --git a/apps/codezero/templates/secret.yaml b/apps/codezero/templates/secret.yaml index f48a62f..5cf2564 100644 --- a/apps/codezero/templates/secret.yaml +++ b/apps/codezero/templates/secret.yaml @@ -8,7 +8,6 @@ type: Opaque stringData: POSTGRES_DB: {{ .Values.postgresql.auth.database | quote }} POSTGRES_USER: {{ .Values.postgresql.auth.username | quote }} - POSTGRES_PASSWORD: {{ .Values.postgresql.auth.password | quote }} POSTGRES_HOST: {{ include "codezero.postgresHost" . | quote }} POSTGRES_PORT: "5432" INITIAL_ROOT_PASSWORD: {{ .Values.admin.password | quote }} @@ -16,3 +15,9 @@ stringData: {{- if .Values.runtime.aquila.sagittariusToken }} AQUILA_SAGITTARIUS_TOKEN: {{ .Values.runtime.aquila.sagittariusToken | quote }} {{- end }} +--- +{{/* +The Postgres password is managed by Bitnami's postgresql subchart. +Sagittarius containers read it from Bitnami's auto-generated secret. +This avoids duplicating the password in two secrets. +*/}} diff --git a/apps/codezero/values.yaml b/apps/codezero/values.yaml index 6eaa382..52aba8d 100644 --- a/apps/codezero/values.yaml +++ b/apps/codezero/values.yaml @@ -21,7 +21,9 @@ postgresql: auth: database: sagittarius_production username: sagittarius - password: sagittarius + # password is auto-generated by Bitnami if not set — stored in a K8s Secret + # To set explicitly: password: "your-password" + # To use an existing secret: existingSecret: "my-pg-secret" primary: persistence: size: 10Gi