Installation

Production installation with Helm

Use the source chart to prepare secrets, PostgreSQL, S3 or RWX storage, ingress/TLS, HPA, PDB, probes, rollout, and rollback end to end.

Content statusVerified in sourceDocumentation versionLatest

Installation topology and prerequisites

The chart deploys Smart Kubaba as a stateless, horizontally scalable application tier. Durable correctness state lives in external or shared services.

  • A Kubernetes 1.24-compatible cluster, Helm 3, and kubectl access; Metrics Server when HPA is enabled.
  • External PostgreSQL reachable from application pods with sufficient max_connections budget.
  • For production, S3-compatible shared object storage or a ReadWriteMany filesystem that every replica genuinely sees as the same content.
  • A pre-created application Secret, imagePullSecret, ingress controller, DNS record, and TLS Secret.
  • At least three eligible worker nodes when hostname spread uses DoNotSchedule; verify zone-spread behavior separately when zone labels are absent.

What resources does the chart create?

Chart templates never generate application credentials; they connect deployment resources to existing platform services.

  • Deployment: non-root UID/GID 999, RollingUpdate with maxUnavailable=0 and maxSurge=1, 10-second minReady, and 600-second progress deadline.
  • Service: ClusterIP with sessionAffinity=None and default port 8080.
  • Ingress: one host, a / Prefix route, selectable ingressClass, and TLS Secret reference.
  • HPA: CPU utilization with 30-second scale-up and 300-second scale-down stabilization; PDB defaults to minAvailable=2.
  • Startup, readiness, and liveness probes; readiness includes PostgreSQL and shared storage, while liveness covers process health only.
  • When persistence is enabled, an existing or chart-created PVC; when disabled, a temporary /data/smart-kubaba emptyDir.

Complete production values.yaml

The example below contains every chart value and uses safe placeholders for an S3-backed HA production profile. image.tag must be replaced with an immutable release.

  • Ingress annotation keys match the source production profile's F5 NGINX Controller; use controller-specific equivalents for ingress-nginx or another controller.
  • When autoscaling.enabled=true, Deployment does not use replicaCount; HPA minReplicas controls the initial replica floor.
  • The 20 GiB ingress limit must align with backend upload bounds; unlimited body size must not be used.
values-production.yamlDownload fileyaml
replicaCount: 3
revisionHistoryLimit: 10
fullnameOverride: smart-kubaba

image:
  repository: kubaba.s3t.co/smart-kubaba
  tag: "REPLACE_WITH_IMMUTABLE_RELEASE"
  pullPolicy: Always
  pullSecrets:
    - kubaba-s3t-co-docker-config

# This Secret must already exist. The chart never creates credentials.
existingSecret: smart-kubaba-secrets

service:
  type: ClusterIP
  port: 8080

ingress:
  enabled: true
  className: nginx
  annotations:
    # F5 NGINX Ingress annotations used by the source production profile.
    # Replace these keys when the cluster uses ingress-nginx or another controller.
    nginx.org/client-max-body-size: "20g"
    nginx.org/proxy-read-timeout: "3600s"
    nginx.org/proxy-send-timeout: "3600s"
  host: kubaba.example.com
  tls:
    enabled: true
    secretName: kubaba-tls

# Recommended production profile: shared S3-compatible object storage.
# Bucket, region, endpoint and optional credentials come from existingSecret.
storage:
  type: S3
  rootDirectory: /data/smart-kubaba/storage
  archiveDirectory: /data/smart-kubaba/archive

# S3 keeps durable application objects outside the pod. The chart still mounts
# an emptyDir at /data/smart-kubaba for bounded temporary OSV work files.
persistence:
  enabled: false
  existingClaim: ""
  storageClass: ""
  accessModes:
    - ReadWriteMany
  size: 100Gi

autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 4
  targetCPUUtilizationPercentage: 70

podDisruptionBudget:
  enabled: true
  minAvailable: 2

resources:
  requests:
    cpu: 500m
    memory: 768Mi
    ephemeral-storage: 1Gi
  limits:
    cpu: "2"
    memory: 2Gi
    ephemeral-storage: 10Gi

javaToolOptions: "-Xms256m -Xmx1280m -XX:+ExitOnOutOfMemoryError"
terminationGracePeriodSeconds: 60
preStopDelaySeconds: 10

# Pool sizes are per pod. Reserve PostgreSQL headroom for migrations,
# administration, monitoring and non-application clients.
databasePool:
  maximumSize: 10
  minimumIdle: 2
  connectionTimeoutMillis: 10000
  validationTimeoutMillis: 5000
  idleTimeoutMillis: 600000
  maxLifetimeMillis: 1800000
  leakDetectionThresholdMillis: 0

probes:
  startup:
    failureThreshold: 24
    periodSeconds: 5
  readiness:
    failureThreshold: 6
    periodSeconds: 10
  liveness:
    failureThreshold: 3
    periodSeconds: 20

nodeSelector: {}
tolerations: []
affinity: {}

topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: ScheduleAnyway

Filesystem/RWX alternative

When filesystem storage is used instead of S3, the same PVC must mount concurrently on every replica. Node-local disk or a ReadWriteOnce volume is not valid for multi-replica production.

  • When existingClaim is empty, the chart creates a PVC from accessModes and size; a pre-tested existing claim is preferred in production.
  • For Longhorn, use a standard non-migratable RWX StorageClass; migratable=true is for block-mode live migration and does not provide the NFS share manager.
Filesystem overrideyaml
# Use this override only with storage shared by every replica.
storage:
  type: FILESYSTEM
  rootDirectory: /data/smart-kubaba/storage
  archiveDirectory: /data/smart-kubaba/archive

persistence:
  enabled: true
  # Prefer a pre-created, tested RWX claim for production.
  existingClaim: smart-kubaba-data-rwx
  storageClass: ""
  accessModes:
    - ReadWriteMany
  size: 100Gi

Secret and image-pull structure

The Kubernetes Secret referenced by existingSecret supplies application environment keys through envFrom. The chart does not create the Secret and real values never belong in values.yaml.

  • PostgreSQL URL, username, and password plus bootstrap-admin username and password must exist in the secret manager before first installation.
  • When S3 access keys are omitted, the backend can use the AWS default credential-provider chain; workload identity or instance role may be preferred.
  • image.pullSecrets references a separate kubernetes.io/dockerconfigjson Secret; Docker config does not belong in the application Secret.
  • The bootstrap-admin initial password is used only when the user does not yet exist; secret rotation and the administrator password policy must be operated separately after installation.
Secret key referencetext
Required for first installation:
SMART_KUBABA_DB_URL
SMART_KUBABA_DB_USERNAME
SMART_KUBABA_DB_PASSWORD
SMART_KUBABA_ADMIN_USERNAME
SMART_KUBABA_ADMIN_INITIAL_PASSWORD

Required when storage.type is S3:
SMART_KUBABA_STORAGE_S3_BUCKET
SMART_KUBABA_STORAGE_S3_REGION

Provider-dependent S3 keys:
SMART_KUBABA_STORAGE_S3_ENDPOINT_URL
SMART_KUBABA_STORAGE_S3_PATH_STYLE_ACCESS
SMART_KUBABA_STORAGE_S3_ACCESS_KEY_ID
SMART_KUBABA_STORAGE_S3_SECRET_ACCESS_KEY

Optional OIDC redirect keys:
SMART_KUBABA_OIDC_SUCCESS_REDIRECT
SMART_KUBABA_OIDC_FAILURE_REDIRECT

The image pull credential is a separate kubernetes.io/dockerconfigjson
Secret named by image.pullSecrets.

Installation steps

The commands are written to run from the D:/workspace/smart-kubaba repository root.

  1. Update image tag, host, TLS Secret, ingress class, storage, and capacity values in values-production.yaml for the target environment.
  2. Create the kubaba namespace, smart-kubaba-secrets, and registry pull Secret through the platform secret manager.
  3. Use helm lint for schema or template errors, then inspect rendered manifests and secret references with helm template.
  4. For the first installation, run helm upgrade --install with an immutable image tag and retain wait and timeout boundaries.
  5. Verify Deployment rollout, pod readiness, Service and Ingress, HPA and PDB, and the readiness endpoint.
Install and render commandsbash
# Run from the Smart Kubaba source repository.
kubectl create namespace kubaba --dry-run=client -o yaml | kubectl apply -f -

# Create smart-kubaba-secrets and the registry pull Secret through the
# platform secret manager before continuing. Do not commit plaintext values.

helm lint ./helm/smart-kubaba   -f values-production.yaml

helm template smart-kubaba ./helm/smart-kubaba   --namespace kubaba   -f values-production.yaml   --set-string image.tag="<release>"   > rendered-smart-kubaba.yaml

helm upgrade --install smart-kubaba ./helm/smart-kubaba   --namespace kubaba   --create-namespace   -f values-production.yaml   --set-string image.tag="<release>"   --wait   --timeout 15m

Installation verification

A successful Helm result is not acceptance by itself. Verify the application, database, storage, package traffic, and operational evidence together.

  • All pods must be Ready, Deployment Available, HPA and PDB in the expected state, and the Ingress TLS certificate valid.
  • Readiness must be UP with healthy PostgreSQL, Flyway, and global shared storage. Liveness must not restart the process unnecessarily during an external dependency outage.
  • Exercise management login, Hosted publish and download, Proxy fetch and cache, Group resolution, and Package Usage, Audit, and Outbound evidence as acceptance scenarios.
  • S3 or RWX storage must serve the same artifact checksum through multiple replicas.
Verification commandsbash
kubectl -n kubaba get deployment,service,ingress,pods,hpa,pdb,pvc
kubectl -n kubaba rollout status deployment/smart-kubaba --timeout=10m
kubectl -n kubaba wait --for=condition=Ready pod -l app=smart-kubaba --timeout=10m

helm -n kubaba status smart-kubaba
helm -n kubaba get values smart-kubaba --all
helm -n kubaba get manifest smart-kubaba > installed-smart-kubaba.yaml

# Readiness includes PostgreSQL and shared-storage availability.
kubectl -n kubaba port-forward service/smart-kubaba 8080:8080
curl --fail --silent --show-error http://127.0.0.1:8080/actuator/health/readiness

Upgrade, rollback, and removal

For established releases, later upgrades can use --atomic to roll back failed rollouts automatically. When adopting existing raw-manifest resources into Helm for the first time, use a waited adoption without automatic cleanup or atomic behavior.

  • Before every upgrade, record the PostgreSQL migration chain, chart appVersion and image tag, and previous Helm revision.
  • Rollback is not only a pod or image rollback; compare Flyway history with the migration set present in the selected code version.
  • helm uninstall does not delete PostgreSQL, the S3 bucket, or external PVC backups; data retention and recovery remain separate operator decisions.
Release lifecyclebash
# Later upgrades: pin an immutable chart/image release and enable atomic rollback.
helm upgrade smart-kubaba ./helm/smart-kubaba   --namespace kubaba   -f values-production.yaml   --set-string image.tag="<new-release>"   --atomic   --wait   --timeout 15m

helm -n kubaba history smart-kubaba

# Select a known-good revision from helm history.
helm -n kubaba rollback smart-kubaba <revision> --wait --timeout 15m

# Removal does not replace PostgreSQL/object-storage recovery planning.
helm -n kubaba uninstall smart-kubaba

Capacity and security boundaries

  • databasePool.maximumSize is per pod. autoscaling.maxReplicas × maximumSize plus migration, administration, monitoring, and other-client headroom must remain below PostgreSQL max_connections.
  • Measure javaToolOptions together with resource limits; setting heap equal to the container memory limit leaves no room for native memory, direct buffers, or JVM overhead.
  • The chart forces SMART_KUBABA_COOKIE_SECURE=true; production management traffic must not be exposed without TLS.
  • Secret values must not be written to Helm command lines, values files, rendered manifests, Git, or CI logs.
  • This chart does not provide backup and restore, RTO/RPO, certificate issuance, PostgreSQL HA, or object-storage durability guarantees; platform runbooks must cover them.