|
Some checks failed
visual-baseline / Capture visual baselines (push) Waiting to run
actionlint / Lint GitHub Actions workflows (push) Failing after 1s
ci / Detect CI change scopes (push) Successful in 0s
nix-check / build (push) Failing after 1s
ci / Validate Nix flake (push) Has been skipped
ci / Preflight (push) Failing after 1s
ci / Workspace unit tests (push) Failing after 1s
ci / Daemon workspace tests (push) Failing after 1s
ci / Web workspace tests (push) Failing after 1s
ci / Browser tests (push) Failing after 1s
ci / Build workspaces (push) Failing after 1s
ci / Validate workspace (push) Failing after 0s
ci / Runtime trace (push) Has been skipped
* introduce MVP Helm chart * address review feedback and add config checksums * implement zero-trust sidecar proxy and fix health probes * address PR feedback on publicBaseUrl and sidecar * pass ingress headers and consolidate proxy port * fallback allowed origins for localhost when ingress is disabled to prevent CORS errors during port-forwarding * enforce proxy security and auto-derive base URL * hardcode service targetPort to proxy * require explicit base url for multi-host ingress * prevent silent CORS failures for LoadBalancer and NodePort and README updates * Added to the deployment pod annotations. This ensures that changes made to during a helm upgrade will properly trigger a rolling update of the pods instead of serving stale proxy configurations * dynamically derive scheme per host in allowed origins * dynamically derive scheme for single-host publicBaseUrl * add default apiToken placeholder and wrap ingress path guardrail * add recent changes to readme * explicitly disallow non-root ingress path prefixes * update README to reflect path and origin guardrails --------- Co-authored-by: shaarron <sharon.kroch@gmail.com> |
||
|---|---|---|
| .. | ||
| templates | ||
| .helmignore | ||
| Chart.yaml | ||
| README.md | ||
| values.yaml | ||
Introduction
This chart bootstraps an Open Design deployment on a Kubernetes cluster using the Helm package manager.
Prerequisites
- Kubernetes 1.23+
- Helm 3.8.0+
- PV provisioner support in the underlying infrastructure (if persistence is enabled)
Installing the Chart
To install the chart with the release name my-release:
helm install my-release ./charts/open-design
These commands deploy an Open Design application on the Kubernetes cluster in the default configuration.
Tip: List all releases using
helm list
Architecture and Configuration Notes
SQLite State & Concurrency Limitations
The current Open Design runtime stores state in local files and SQLite under /app/.od. Because SQLite does not support concurrent writes from multiple network replicas, this chart is strictly limited to 1 replica.
Horizontal Pod Autoscaling (HPA) is disabled by default. Do not enable HPA or scale the deployment beyond replicas: 1 unless you have modified the application to externalize the state to a standalone database.
Server-Sent Events (SSE) and Ingress
Open Design relies on Server-Sent Events (SSE) for real-time streaming. If you enable the Ingress resource, it is critical to disable reverse-proxy buffering. If you are using the NGINX Ingress Controller, this chart automatically applies the required annotations by default:
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
Path Constraints: Non-root ingress path prefixes (sub-paths) are explicitly unsupported by the proxy routing stack. Ingress paths must be configured as /.
Authentication Proxy
An authentication proxy (NGINX) is introduced to front the application. This proxy runs as a mandatory sidecar container alongside the main application. The Kubernetes Service routes traffic to the proxy, which handles authentication for the API and health checks, proxying valid requests to the application.
Security Context
This chart adheres to strict security defaults:
- Runs as non-root user
1001. - Drops all kernel capabilities (
ALL). - Enforces a
readOnlyRootFilesystem. - Prevents privilege escalation.
Parameters
Global & Image Parameters
| Name | Description | Value |
|---|---|---|
commonLabels |
Custom labels injected into all resources | {app.kubernetes.io/environment: production} |
image.repository |
Open Design image repository | vanjayak/open-design |
image.pullPolicy |
Image pull policy | IfNotPresent |
image.tag |
Image tag (overrides AppVersion) | latest |
Application Configuration
| Name | Description | Value |
|---|---|---|
config.nodeEnv |
Node.js environment (production or development) |
production |
config.allowedOrigins |
CORS allowed origins. Mandatory if service.type is LoadBalancer or NodePort to prevent 403 render failures. | "" |
config.publicBaseUrl |
Public base URL used by the application (derived dynamically if empty) | "" |
config.nodeOptions |
V8 engine memory optimizations | --max-old-space-size=192 |
config.webPort |
Web server listening port | 7456 |
config.bindHost |
Host to bind the web server to | "127.0.0.1" |
config.apiToken |
API authentication token (must be changed from default) | "secure-default-token-change-me" |
Auth Proxy Parameters
| Name | Description | Value |
|---|---|---|
authProxy.image |
NGINX proxy image | nginxinc/nginx-unprivileged:1.25-alpine-slim |
authProxy.port |
Proxy server port inside the container | 8080 |
authProxy.securityContext |
Security context for the proxy container | {...} |
Health Check Parameters
| Name | Description | Value |
|---|---|---|
livenessProbe.enabled |
Enable liveness probe | true |
livenessProbe.initialDelaySeconds |
Initial delay seconds for liveness probe | 20 |
livenessProbe.periodSeconds |
Period seconds for liveness probe | 30 |
livenessProbe.timeoutSeconds |
Timeout seconds for liveness probe | 5 |
livenessProbe.failureThreshold |
Failure threshold for liveness probe | 3 |
readinessProbe.enabled |
Enable readiness probe | true |
readinessProbe.initialDelaySeconds |
Initial delay seconds for readiness probe | 5 |
readinessProbe.periodSeconds |
Period seconds for readiness probe | 10 |
readinessProbe.timeoutSeconds |
Timeout seconds for readiness probe | 5 |
readinessProbe.failureThreshold |
Failure threshold for readiness probe | 3 |
Network & Ingress Parameters
| Name | Description | Value |
|---|---|---|
service.type |
Kubernetes Service type | ClusterIP |
service.port |
Service HTTP port | 80 |
ingress.enabled |
Enable ingress record generation | false |
ingress.className |
Ingress class name | nginx |
ingress.annotations |
Additional custom annotations for Ingress (e.g., SSE fixes) | {...} |
ingress.hosts[0].host |
Hostname for the ingress record | open-design.local |
ingress.tls |
TLS configuration for ingress records | [] |
Persistence Parameters
| Name | Description | Value |
|---|---|---|
persistence.enabled |
Enable PVC for SQLite and file state | true |
persistence.storageClass |
Storage class (leave empty to use cluster default) | "" |
persistence.accessMode |
PVC Access Mode | ReadWriteOnce |
persistence.size |
PVC Storage Request | 10Gi |
Resources & Autoscaling Parameters
| Name | Description | Value |
|---|---|---|
replicaCount |
Number of application replicas | 1 |
resources.limits.cpu |
CPU limits for the container | 1000m |
resources.limits.memory |
Memory limits for the container | 1024Mi |
resources.requests.cpu |
CPU requests for the container | 200m |
resources.requests.memory |
Memory requests for the container | 256Mi |
hpa.enabled |
Enable Horizontal Pod Autoscaler (WARNING: Breaks SQLite) | false |
Security & Scheduling Parameters
| Name | Description | Value |
|---|---|---|
podSecurityContext.fsGroupChangePolicy |
Set filesystem group change policy | Always |
podSecurityContext.sysctls |
Set kernel settings using the sysctl interface | [] |
podSecurityContext.supplementalGroups |
Set filesystem extra groups | [] |
podSecurityContext.fsGroup |
Group ID for the persistent volume | 1001 |
containerSecurityContext.seLinuxOptions |
Set SELinux options in container | {} |
containerSecurityContext.runAsUser |
Run the application as this UID | 1001 |
containerSecurityContext.runAsGroup |
Run the application as this GID | 1001 |
containerSecurityContext.runAsNonRoot |
Set container's Security Context runAsNonRoot | true |
containerSecurityContext.privileged |
Set container's Security Context privileged | false |
containerSecurityContext.readOnlyRootFilesystem |
Enforce read-only root FS | true |
containerSecurityContext.allowPrivilegeEscalation |
Set container's Security Context allowPrivilegeEscalation | false |
containerSecurityContext.capabilities.drop |
List of capabilities to be dropped | ["ALL"] |
containerSecurityContext.seccompProfile.type |
Set container's Security Context seccomp profile | "RuntimeDefault" |
nodeSelector |
Node labels for pod assignment | {} |
tolerations |
Tolerations for pod assignment | [] |
affinity |
Affinity rules for pod assignment | {} |
initContainers |
Additional init containers to add to the pod | [] |
sidecars |
Additional sidecar containers to add to the pod | [] |
Specify each parameter using the --set key=value[,key=value] argument to helm install. For example,
helm install my-release --set config.nodeEnv=development ./charts/open-design
The above command sets the Open Design node environment to development.
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
helm install my-release -f values.yaml ./charts/open-design
Tip: You can use the default values.yaml