From c208d29cadc79e17d9f49a6f9687a9cfecd93902 Mon Sep 17 00:00:00 2001 From: Philip Meier Date: Wed, 30 Sep 2026 16:53:27 +0200 Subject: [PATCH 1/2] use official NebariApp CR template --- .github/workflows/lint.yaml | 6 ++ .github/workflows/test-integration.yaml | 2 + .github/workflows/test.yaml | 6 ++ examples/auth-fastapi/chart/Chart.lock | 6 ++ examples/auth-fastapi/chart/Chart.yaml | 6 +- .../chart/templates/nebariapp.yaml | 55 +++--------------- examples/auth-fastapi/chart/values.yaml | 11 ++-- examples/basic-nginx/chart/Chart.lock | 6 ++ examples/basic-nginx/chart/Chart.yaml | 6 +- .../chart/templates/nebariapp.yaml | 56 +++---------------- examples/basic-nginx/chart/values.yaml | 11 ++-- examples/wrap-existing-chart/chart/Chart.lock | 7 ++- examples/wrap-existing-chart/chart/Chart.yaml | 5 +- .../chart/templates/nebariapp.yaml | 56 +++---------------- .../wrap-existing-chart/chart/values.yaml | 10 ++-- 15 files changed, 90 insertions(+), 159 deletions(-) create mode 100644 examples/auth-fastapi/chart/Chart.lock create mode 100644 examples/basic-nginx/chart/Chart.lock diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index b99646c..819105c 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -39,6 +39,9 @@ jobs: run: kubectl kustomize examples/kustomize-nginx/overlays/production/ | kubeconform -strict -ignore-missing-schemas # Basic nginx Helm example + - name: Build basic-nginx dependencies + run: helm dependency build examples/basic-nginx/chart/ + - name: Lint basic-nginx run: helm lint examples/basic-nginx/chart/ @@ -49,6 +52,9 @@ jobs: run: helm template test examples/basic-nginx/chart/ --set nebariapp.enabled=true --set nebariapp.hostname=test.example.com # Auth-aware FastAPI Helm example + - name: Build auth-fastapi dependencies + run: helm dependency build examples/auth-fastapi/chart/ + - name: Lint auth-fastapi run: helm lint examples/auth-fastapi/chart/ diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 77c437c..1871387 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -162,6 +162,7 @@ jobs: # ============================================================ - name: "Deploy basic-nginx" run: | + helm dependency build examples/basic-nginx/chart/ helm install test-basic examples/basic-nginx/chart/ \ --set nebariapp.enabled=true \ --set nebariapp.hostname=basic.nebari.local \ @@ -183,6 +184,7 @@ jobs: # ============================================================ - name: "Deploy auth-fastapi" run: | + helm dependency build examples/auth-fastapi/chart/ helm install test-fastapi examples/auth-fastapi/chart/ \ --set nebariapp.enabled=true \ --set nebariapp.hostname=fastapi.nebari.local \ diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9541bdf..4c05392 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -63,6 +63,9 @@ jobs: run: kubectl delete namespace test-kustomize --wait # Test basic nginx Helm example + - name: Build basic-nginx dependencies + run: helm dependency build examples/basic-nginx/chart/ + - name: Install basic-nginx chart run: | helm install test-basic examples/basic-nginx/chart/ \ @@ -89,6 +92,9 @@ jobs: docker build -t ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest examples/auth-fastapi/ kind load docker-image ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest --name pack-test + - name: Build auth-fastapi dependencies + run: helm dependency build examples/auth-fastapi/chart/ + - name: Install auth-fastapi chart run: | helm install test-fastapi examples/auth-fastapi/chart/ \ diff --git a/examples/auth-fastapi/chart/Chart.lock b/examples/auth-fastapi/chart/Chart.lock new file mode 100644 index 0000000..9a83e5b --- /dev/null +++ b/examples/auth-fastapi/chart/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: nebari-app + repository: oci://quay.io/nebari/charts + version: 0.1.1 +digest: sha256:23d36f9038fee9ae9b35efc6de107a10d291416fa26695602f6f37dec68cfeec +generated: "2026-09-30T15:04:08.075381765Z" diff --git a/examples/auth-fastapi/chart/Chart.yaml b/examples/auth-fastapi/chart/Chart.yaml index eed5516..1d72e4c 100644 --- a/examples/auth-fastapi/chart/Chart.yaml +++ b/examples/auth-fastapi/chart/Chart.yaml @@ -2,5 +2,9 @@ apiVersion: v2 name: my-pack description: A Nebari Software Pack with auth-aware FastAPI application type: application -version: 0.1.1 +version: 0.1.2 appVersion: "1.0.0" +dependencies: + - name: nebari-app + repository: oci://quay.io/nebari/charts + version: ">=0.1.1" diff --git a/examples/auth-fastapi/chart/templates/nebariapp.yaml b/examples/auth-fastapi/chart/templates/nebariapp.yaml index 0d99104..52df009 100644 --- a/examples/auth-fastapi/chart/templates/nebariapp.yaml +++ b/examples/auth-fastapi/chart/templates/nebariapp.yaml @@ -1,48 +1,11 @@ -{{/* - NebariApp Custom Resource - -------------------------- - When deployed on a Nebari cluster with nebariapp.enabled=true, this resource - tells the nebari-operator to auto-configure routing, TLS, and OIDC auth. - - For this auth-aware example, auth is enabled by default in values.yaml. - After authentication, the Envoy Gateway OIDC filter sets an IdToken cookie - that the FastAPI app reads to display user information. -*/}} {{- if .Values.nebariapp.enabled }} -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -metadata: - name: {{ include "my-pack.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "my-pack.labels" . | nindent 4 }} -spec: - hostname: {{ required "nebariapp.hostname is required when nebariapp.enabled is true" .Values.nebariapp.hostname }} - service: - name: {{ .Values.nebariapp.service.name | default (include "my-pack.fullname" .) }} - port: {{ .Values.nebariapp.service.port | default 80 }} - {{- with .Values.nebariapp.routing }} - routing: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.nebariapp.auth }} - auth: - enabled: {{ .enabled | default true }} - provider: {{ .provider | default "keycloak" }} - provisionClient: {{ .provisionClient | default true }} - {{- with .redirectURI }} - redirectURI: {{ . }} - {{- end }} - {{- with .scopes }} - scopes: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .groups }} - groups: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- end }} - {{- with .Values.nebariapp.gateway }} - gateway: {{ . }} - {{- end }} +{{- include "nebari-app.nebariApp" (dict + "metadata" (dict + "name" (include "my-pack.fullname" .) + "namespace" .Release.Namespace + "labels" (include "my-pack.labels" . | fromYaml) + ) + "spec" (omit .Values.nebariapp "enabled") + "tplCtx" . +) -}} {{- end }} diff --git a/examples/auth-fastapi/chart/values.yaml b/examples/auth-fastapi/chart/values.yaml index 48f1476..e9e701a 100644 --- a/examples/auth-fastapi/chart/values.yaml +++ b/examples/auth-fastapi/chart/values.yaml @@ -27,14 +27,15 @@ resources: {} # ============================================================================= # Nebari Integration # ============================================================================= -# Creates a NebariApp CRD that configures routing, TLS, and auth via nebari-operator. -# This example enables auth by default since the app is designed to read IdToken cookies. +# NebariApp CR (https://github.com/nebari-dev/nebari-operator). +# Rendered through the official nebari-app.nebariApp template +# (https://github.com/nebari-dev/nebari-operator/tree/main/charts/nebari-app) with templating enabled. nebariapp: enabled: false - # hostname: my-pack.nebari.example.com # Required when enabled + hostname: '{{ fail "nebariapp.hostname is required when nebariapp.enabled is true" }}' service: - name: "" # Defaults to release fullname - port: 80 + name: '{{ include "my-pack.fullname" . | toJson }}' + port: '{{ .Values.service.port }}' routing: routes: - pathPrefix: / diff --git a/examples/basic-nginx/chart/Chart.lock b/examples/basic-nginx/chart/Chart.lock new file mode 100644 index 0000000..7cb8559 --- /dev/null +++ b/examples/basic-nginx/chart/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: nebari-app + repository: oci://quay.io/nebari/charts + version: 0.1.1 +digest: sha256:23d36f9038fee9ae9b35efc6de107a10d291416fa26695602f6f37dec68cfeec +generated: "2026-09-30T15:00:54.569394784Z" diff --git a/examples/basic-nginx/chart/Chart.yaml b/examples/basic-nginx/chart/Chart.yaml index c22caa2..dcbbcaa 100644 --- a/examples/basic-nginx/chart/Chart.yaml +++ b/examples/basic-nginx/chart/Chart.yaml @@ -2,5 +2,9 @@ apiVersion: v2 name: my-pack description: A Nebari Software Pack (replace with your description) type: application -version: 0.1.0 +version: 0.1.1 appVersion: "1.0.0" +dependencies: + - name: nebari-app + repository: oci://quay.io/nebari/charts + version: ">=0.1.1" diff --git a/examples/basic-nginx/chart/templates/nebariapp.yaml b/examples/basic-nginx/chart/templates/nebariapp.yaml index 0eda596..52df009 100644 --- a/examples/basic-nginx/chart/templates/nebariapp.yaml +++ b/examples/basic-nginx/chart/templates/nebariapp.yaml @@ -1,49 +1,11 @@ -{{/* - NebariApp Custom Resource - -------------------------- - When deployed on a Nebari cluster with nebariapp.enabled=true, this resource - tells the nebari-operator to auto-configure: - - HTTPRoute (routing traffic from the shared Gateway to your Service) - - TLS certificate (via cert-manager) - - OIDC authentication (via Keycloak + Envoy Gateway SecurityPolicy) - - Outside of Nebari, leave nebariapp.enabled=false and this template is skipped. -*/}} {{- if .Values.nebariapp.enabled }} -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -metadata: - name: {{ include "my-pack.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "my-pack.labels" . | nindent 4 }} -spec: - hostname: {{ required "nebariapp.hostname is required when nebariapp.enabled is true" .Values.nebariapp.hostname }} - service: - name: {{ .Values.nebariapp.service.name | default (include "my-pack.fullname" .) }} - port: {{ .Values.nebariapp.service.port | default 80 }} - {{- with .Values.nebariapp.routing }} - routing: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.nebariapp.auth }} - auth: - enabled: {{ .enabled | default false }} - provider: {{ .provider | default "keycloak" }} - provisionClient: {{ .provisionClient | default true }} - {{- with .redirectURI }} - redirectURI: {{ . }} - {{- end }} - {{- with .scopes }} - scopes: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .groups }} - groups: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- end }} - {{- with .Values.nebariapp.gateway }} - gateway: {{ . }} - {{- end }} +{{- include "nebari-app.nebariApp" (dict + "metadata" (dict + "name" (include "my-pack.fullname" .) + "namespace" .Release.Namespace + "labels" (include "my-pack.labels" . | fromYaml) + ) + "spec" (omit .Values.nebariapp "enabled") + "tplCtx" . +) -}} {{- end }} diff --git a/examples/basic-nginx/chart/values.yaml b/examples/basic-nginx/chart/values.yaml index 3af5125..438bc53 100644 --- a/examples/basic-nginx/chart/values.yaml +++ b/examples/basic-nginx/chart/values.yaml @@ -26,14 +26,15 @@ resources: {} # ============================================================================= # Nebari Integration # ============================================================================= -# Creates a NebariApp CRD that configures routing, TLS, and auth via nebari-operator. -# Set enabled: true when deploying on a Nebari cluster. +# NebariApp CR (https://github.com/nebari-dev/nebari-operator). +# Rendered through the official nebari-app.nebariApp template +# (https://github.com/nebari-dev/nebari-operator/tree/main/charts/nebari-app) with templating enabled. nebariapp: enabled: false - # hostname: my-pack.nebari.example.com # Required when enabled + hostname: '{{ fail "nebariapp.hostname is required when nebariapp.enabled is true" }}' service: - name: "" # Defaults to release fullname - port: 80 + name: '{{ include "my-pack.fullname" . | toJson }}' + port: '{{ .Values.service.port }}' auth: enabled: false provider: keycloak diff --git a/examples/wrap-existing-chart/chart/Chart.lock b/examples/wrap-existing-chart/chart/Chart.lock index 840024d..28d631d 100644 --- a/examples/wrap-existing-chart/chart/Chart.lock +++ b/examples/wrap-existing-chart/chart/Chart.lock @@ -1,6 +1,9 @@ dependencies: +- name: nebari-app + repository: oci://quay.io/nebari/charts + version: 0.1.1 - name: podinfo repository: oci://ghcr.io/stefanprodan/charts version: 6.10.1 -digest: sha256:78da911b578ebe6b5f207d6a601d631a8dfb8224498a3e0f2b8a71286f80d420 -generated: "2026-02-27T10:08:47.117820474+01:00" +digest: sha256:e73d977132fbbb002d2cec54cffe94d7d3f4212b9ec66f87060692612d3ee066 +generated: "2026-09-30T15:00:55.665759533Z" diff --git a/examples/wrap-existing-chart/chart/Chart.yaml b/examples/wrap-existing-chart/chart/Chart.yaml index 17ff6f9..5041671 100644 --- a/examples/wrap-existing-chart/chart/Chart.yaml +++ b/examples/wrap-existing-chart/chart/Chart.yaml @@ -2,9 +2,12 @@ apiVersion: v2 name: my-pack description: A Nebari Software Pack wrapping Podinfo type: application -version: 0.1.0 +version: 0.1.1 appVersion: "6.10.1" dependencies: + - name: nebari-app + repository: oci://quay.io/nebari/charts + version: ">=0.1.1" - name: podinfo version: 6.10.1 repository: oci://ghcr.io/stefanprodan/charts diff --git a/examples/wrap-existing-chart/chart/templates/nebariapp.yaml b/examples/wrap-existing-chart/chart/templates/nebariapp.yaml index 66334f6..52df009 100644 --- a/examples/wrap-existing-chart/chart/templates/nebariapp.yaml +++ b/examples/wrap-existing-chart/chart/templates/nebariapp.yaml @@ -1,49 +1,11 @@ -{{/* - NebariApp Custom Resource - -------------------------- - This is the key integration point when wrapping an existing Helm chart. - The NebariApp points to the upstream chart's Service (podinfo in this case), - telling the nebari-operator to configure routing, TLS, and auth for it. - - You do NOT need to create your own Deployment or Service - the upstream chart - handles that. You just create a NebariApp that points to the upstream service. -*/}} {{- if .Values.nebariapp.enabled }} -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -metadata: - name: {{ include "my-pack.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "my-pack.labels" . | nindent 4 }} -spec: - hostname: {{ required "nebariapp.hostname is required when nebariapp.enabled is true" .Values.nebariapp.hostname }} - service: - # Point to the upstream chart's service. For podinfo, this is -podinfo. - name: {{ .Values.nebariapp.service.name | default (include "my-pack.podinfo-service-name" .) }} - port: {{ .Values.nebariapp.service.port | default 9898 }} - {{- with .Values.nebariapp.routing }} - routing: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.nebariapp.auth }} - auth: - enabled: {{ .enabled | default false }} - provider: {{ .provider | default "keycloak" }} - provisionClient: {{ .provisionClient | default true }} - {{- with .redirectURI }} - redirectURI: {{ . }} - {{- end }} - {{- with .scopes }} - scopes: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .groups }} - groups: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- end }} - {{- with .Values.nebariapp.gateway }} - gateway: {{ . }} - {{- end }} +{{- include "nebari-app.nebariApp" (dict + "metadata" (dict + "name" (include "my-pack.fullname" .) + "namespace" .Release.Namespace + "labels" (include "my-pack.labels" . | fromYaml) + ) + "spec" (omit .Values.nebariapp "enabled") + "tplCtx" . +) -}} {{- end }} diff --git a/examples/wrap-existing-chart/chart/values.yaml b/examples/wrap-existing-chart/chart/values.yaml index 8db9dc3..ffd7246 100644 --- a/examples/wrap-existing-chart/chart/values.yaml +++ b/examples/wrap-existing-chart/chart/values.yaml @@ -4,13 +4,15 @@ # ============================================================================= # Nebari Integration # ============================================================================= -# Creates a NebariApp CRD that configures routing, TLS, and auth via nebari-operator. -# Set enabled: true when deploying on a Nebari cluster. +# NebariApp CR (https://github.com/nebari-dev/nebari-operator). +# Rendered through the official nebari-app.nebariApp template +# (https://github.com/nebari-dev/nebari-operator/tree/main/charts/nebari-app) with templating enabled. nebariapp: enabled: false - # hostname: my-pack.nebari.example.com # Required when enabled + hostname: '{{ fail "nebariapp.hostname is required when nebariapp.enabled is true" }}' service: - name: "" # Defaults to -podinfo (the upstream service name) + # Points to the upstream podinfo chart's service + name: '{{ include "my-pack.podinfo-service-name" . | toJson }}' port: 9898 auth: enabled: false From 85778c05174f2099c5f66e441dd01e6e52e17503 Mon Sep 17 00:00:00 2001 From: Khuyen Tran Date: Thu, 1 Oct 2026 15:31:04 +0700 Subject: [PATCH 2/2] docs: document nebari-app library chart usage (#33) * docs: document nebari-app library chart usage * docs: address review feedback on nebari-app docs --- README.md | 107 +++++++++++++++++++------ docs/site/src/content/docs/concepts.md | 47 ++++++----- examples/auth-fastapi/README.md | 7 +- examples/basic-nginx/README.md | 13 ++- examples/wrap-existing-chart/README.md | 23 ++++-- 5 files changed, 135 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 25ce005..8c78722 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,8 @@ For local development (optional): -f examples/vanilla-yaml/service.yaml kubectl port-forward svc/my-pack 8080:80 - # Or with Helm + # Or with Helm (fetch the nebari-app dependency first) + helm dependency build examples/basic-nginx/chart/ helm install test examples/basic-nginx/chart/ kubectl port-forward svc/test-my-pack 8080:80 @@ -144,11 +145,12 @@ software-pack-template/ README.md basic-nginx/ # Example 3: Simplest Helm chart chart/ - Chart.yaml - values.yaml + Chart.yaml # Has nebari-app as a dependency + Chart.lock + values.yaml # NebariApp config under nebariapp: templates/ _helpers.tpl # Name, label, selector helpers - nebariapp.yaml # NebariApp CRD (conditional) + nebariapp.yaml # Renders the NebariApp via nebari-app (conditional) deployment.yaml # Kubernetes Deployment service.yaml # ClusterIP Service NOTES.txt # Post-install instructions @@ -163,12 +165,12 @@ software-pack-template/ README.md wrap-existing-chart/ # Example 5: Wrapping podinfo via Helm chart/ - Chart.yaml # Has podinfo as a dependency + Chart.yaml # Has podinfo and nebari-app as dependencies Chart.lock values.yaml # Podinfo overrides + NebariApp config templates/ _helpers.tpl - nebariapp.yaml # Points to podinfo's service + nebariapp.yaml # Renders the NebariApp via nebari-app NOTES.txt README.md dev/ @@ -233,20 +235,60 @@ spec: ``` The NebariApp is just a Kubernetes resource. It can live in a plain YAML file, a -Kustomize base, or a Helm template. In Helm charts, you can make the NebariApp -conditional so the chart works both standalone and on Nebari: - -```yaml -{{- if .Values.nebariapp.enabled }} -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -... -{{- end }} -``` +Kustomize base, or a Helm template. With plain YAML or Kustomize, the NebariApp manifest is always present. When deploying standalone, simply skip that file or exclude it from your apply command. +### NebariApp in Helm charts + +To render the NebariApp in a Helm chart with the official +[`nebari-app` library chart](https://github.com/nebari-dev/nebari-operator/tree/main/charts/nebari-app): + +1. Add it as a dependency in `Chart.yaml`, then run `helm dependency build`: + + ```yaml + dependencies: + - name: nebari-app + repository: oci://quay.io/nebari/charts + version: ">=0.1.1" + ``` + +2. Set any NebariApp `spec` field under `nebariapp:` in `values.yaml`: + + ```yaml + nebariapp: + enabled: false + hostname: '{{ fail "nebariapp.hostname is required when nebariapp.enabled is true" }}' + service: + name: '{{ include "my-pack.fullname" . | toJson }}' + port: '{{ .Values.service.port }}' + ``` + +3. Render it in `templates/nebariapp.yaml`. The `if` makes the NebariApp optional, + so the chart works both standalone and on Nebari: + + ```yaml + {{- if .Values.nebariapp.enabled }} + {{- include "nebari-app.nebariApp" (dict + "metadata" (dict + "name" (include "my-pack.fullname" .) + "namespace" .Release.Namespace + "labels" (include "my-pack.labels" . | fromYaml) + ) + "spec" (omit .Values.nebariapp "enabled") + "tplCtx" . + ) -}} + {{- end }} + ``` + +When a `{{ ... }}` value renders a string, add `| toJson` at the end. It wraps the string in quotes so it's valid JSON: + +```yaml +name: '{{ include "my-pack.fullname" . | toJson }}' # works +name: '{{ include "my-pack.fullname" . }}' # fails to render +``` + ### Beyond the basics The fields shown above cover the common cases. The operator also supports several @@ -329,7 +371,7 @@ See [examples/kustomize-nginx/README.md](examples/kustomize-nginx/README.md) for ## Example 3: Helm - Basic Pack (Nginx) The simplest possible Helm-based pack. Deploys a stock nginx container with -optional Nebari integration via a conditional NebariApp template. +optional Nebari integration via the `nebari-app` library chart. **What it demonstrates:** - Minimum viable Helm chart structure @@ -337,6 +379,9 @@ optional Nebari integration via a conditional NebariApp template. - Toggling between standalone and Nebari modes ```bash +# Fetch the nebari-app dependency +helm dependency build examples/basic-nginx/chart/ + # Deploy standalone helm install test-basic examples/basic-nginx/chart/ kubectl port-forward svc/test-basic-my-pack 8080:80 @@ -386,6 +431,7 @@ def get_id_token(request: Request) -> str | None: docker run -p 8000:8000 ghcr.io/nebari-dev/software-pack-template/auth-fastapi-example:latest # Deploy on Nebari with auth +helm dependency build examples/auth-fastapi/chart/ helm install my-pack examples/auth-fastapi/chart/ \ --set nebariapp.enabled=true \ --set nebariapp.hostname=my-pack.nebari.example.com @@ -397,8 +443,7 @@ See [examples/auth-fastapi/README.md](examples/auth-fastapi/README.md) for the f **This is the most realistic Helm use case.** Most Helm-based packs wrap existing software - you don't write your own Deployment or Service. You add -the upstream chart as a dependency and create a NebariApp that points to its -service. +the upstream chart as a dependency and point the NebariApp at its service. **What it demonstrates:** - Chart.yaml dependency on an existing chart @@ -407,19 +452,22 @@ service. - No custom Deployment or Service templates needed ```yaml -# Chart.yaml - just add the dependency +# Chart.yaml - add the upstream chart next to nebari-app dependencies: + - name: nebari-app + repository: oci://quay.io/nebari/charts + version: ">=0.1.1" - name: podinfo version: 6.10.1 repository: oci://ghcr.io/stefanprodan/charts ``` -The only template you write is `nebariapp.yaml`, which points to podinfo's service: +The NebariApp points to podinfo's service from `values.yaml`: ```yaml -spec: +nebariapp: service: - name: {{ .Release.Name }}-podinfo # Upstream service + name: '{{ printf "%s-podinfo" .Release.Name | toJson }}' # Upstream service port: 9898 ``` @@ -708,6 +756,7 @@ kubectl apply -k examples/kustomize-nginx/overlays/production/ \ ### Option D: Helm install ```bash +helm dependency build ./chart/ helm install my-pack ./chart/ \ --namespace my-pack \ --create-namespace \ @@ -859,9 +908,17 @@ naming convention (usually `-`). kubectl logs -n envoy-gateway-system -l app=envoy-gateway ``` -### `helm dependency update` fails for wrapped charts +### `missing in charts/ directory: nebari-app` + +The Helm examples depend on the `nebari-app` chart. Fetch it before installing: + +```bash +helm dependency build examples/basic-nginx/chart/ +``` + +### `helm dependency update` fails -For OCI-based dependencies, ensure Helm 3.8+ is installed: +The dependencies are pulled from OCI registries, so ensure Helm 3.8+ is installed: ```bash helm version diff --git a/docs/site/src/content/docs/concepts.md b/docs/site/src/content/docs/concepts.md index b105b69..28db1bf 100644 --- a/docs/site/src/content/docs/concepts.md +++ b/docs/site/src/content/docs/concepts.md @@ -13,20 +13,20 @@ Every software pack has exactly one integration point with the Nebari platform: automatically configures routing, TLS, and authentication. The NebariApp is just a Kubernetes resource - it can live in a plain YAML file, a -Kustomize base, or a Helm template. In Helm charts, you typically make it conditional -so the chart works both standalone and on Nebari: +Kustomize base, or a Helm template. In Helm charts, render it with the template from the +official [`nebari-app` library chart](https://github.com/nebari-dev/nebari-operator/tree/main/charts/nebari-app). +You typically make it conditional so the chart works both standalone and on Nebari: ```yaml {{- if .Values.nebariapp.enabled }} -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -metadata: - name: {{ include "my-pack.fullname" . }} -spec: - hostname: {{ required "nebariapp.hostname is required" .Values.nebariapp.hostname }} - service: - name: {{ include "my-pack.fullname" . }} - port: 80 +{{- include "nebari-app.nebariApp" (dict + "metadata" (dict + "name" (include "my-pack.fullname" .) + "namespace" .Release.Namespace + ) + "spec" (omit .Values.nebariapp "enabled") + "tplCtx" . +) -}} {{- end }} ``` @@ -70,30 +70,33 @@ Best for: packs deployed to multiple environments with known configuration diffe ### Helm Helm is the most common choice for packs that wrap existing upstream software. You add -the upstream chart as a dependency and add a NebariApp template that points to its -service - you do not rewrite the app. +the upstream chart and `nebari-app` as dependencies, then point the NebariApp at the +upstream service in `values.yaml` - you do not rewrite the app. ```yaml -# Chart.yaml - add the upstream chart as a dependency +# Chart.yaml - add the upstream chart next to nebari-app dependencies: + - name: nebari-app + repository: oci://quay.io/nebari/charts + version: ">=0.1.1" - name: podinfo version: 6.10.1 repository: oci://ghcr.io/stefanprodan/charts ``` ```yaml -# templates/nebariapp.yaml - the only template you write -{{- if .Values.nebariapp.enabled }} -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -spec: - hostname: {{ .Values.nebariapp.hostname }} +# values.yaml - the NebariApp spec +nebariapp: + enabled: false + hostname: '{{ fail "nebariapp.hostname is required when nebariapp.enabled is true" }}' service: - name: {{ .Release.Name }}-podinfo # upstream service name + name: '{{ printf "%s-podinfo" .Release.Name | toJson }}' # upstream service name port: 9898 -{{- end }} ``` +`templates/nebariapp.yaml` is the same short `include` shown above. Run +`helm dependency build` before installing. + Best for: wrapping existing Helm charts and for packs with rich configuration needs. ## Template examples diff --git a/examples/auth-fastapi/README.md b/examples/auth-fastapi/README.md index aaa8ab0..eb2b7ec 100644 --- a/examples/auth-fastapi/README.md +++ b/examples/auth-fastapi/README.md @@ -66,6 +66,7 @@ spec: ### Helm install ```bash +helm dependency build ./chart/ helm install my-pack ./chart/ \ --set nebariapp.enabled=true \ --set nebariapp.hostname=my-pack.nebari.example.com \ @@ -117,10 +118,10 @@ an explanatory message when no IdToken is present. | `app/requirements.txt` | Python dependencies | | `app/templates/index.html` | HTML template for user info display | | `Dockerfile` | Multi-stage build for the FastAPI image | -| `chart/Chart.yaml` | Helm chart metadata | -| `chart/values.yaml` | Default config with auth enabled | +| `chart/Chart.yaml` | Helm chart metadata with the nebari-app dependency | +| `chart/values.yaml` | Default config, including the NebariApp spec with auth enabled | | `chart/templates/_helpers.tpl` | Name, label, and selector helpers | -| `chart/templates/nebariapp.yaml` | NebariApp CRD with auth configuration | +| `chart/templates/nebariapp.yaml` | Renders the NebariApp via nebari-app | | `chart/templates/deployment.yaml` | Kubernetes Deployment | | `chart/templates/service.yaml` | ClusterIP Service | | `chart/templates/NOTES.txt` | Post-install instructions | diff --git a/examples/basic-nginx/README.md b/examples/basic-nginx/README.md index 56dcb2c..2a04af5 100644 --- a/examples/basic-nginx/README.md +++ b/examples/basic-nginx/README.md @@ -6,7 +6,8 @@ container with optional Nebari platform integration via the NebariApp CRD. ## What This Example Shows - Minimum viable Helm chart structure for a Nebari pack -- The `nebariapp.yaml` template that creates a NebariApp custom resource +- Rendering the NebariApp custom resource with the official + [`nebari-app` library chart](https://github.com/nebari-dev/nebari-operator/tree/main/charts/nebari-app) - How to toggle Nebari integration on/off with `nebariapp.enabled` - Health probes, service, and deployment boilerplate @@ -65,6 +66,9 @@ This additionally creates: ### Helm install ```bash +# Fetch the nebari-app dependency +helm dependency build ./chart/ + # Deploy on Nebari helm install my-pack ./chart/ \ --set nebariapp.enabled=true \ @@ -80,6 +84,7 @@ helm install my-pack ./chart/ \ ## Local development (standalone, no Nebari) ```bash +helm dependency build ./chart/ helm install test-basic ./chart/ # Access via port-forward @@ -91,10 +96,10 @@ kubectl port-forward svc/test-basic-my-pack 8080:80 | File | Purpose | |------|---------| -| `chart/Chart.yaml` | Helm chart metadata | -| `chart/values.yaml` | Default configuration values | +| `chart/Chart.yaml` | Helm chart metadata with the nebari-app dependency | +| `chart/values.yaml` | Default configuration values, including the NebariApp spec under `nebariapp:` | | `chart/templates/_helpers.tpl` | Name, label, and selector helpers | -| `chart/templates/nebariapp.yaml` | NebariApp CRD (conditional on `nebariapp.enabled`) | +| `chart/templates/nebariapp.yaml` | Renders the NebariApp via nebari-app (conditional on `nebariapp.enabled`) | | `chart/templates/deployment.yaml` | Kubernetes Deployment for nginx | | `chart/templates/service.yaml` | ClusterIP Service | | `chart/templates/NOTES.txt` | Post-install instructions | diff --git a/examples/wrap-existing-chart/README.md b/examples/wrap-existing-chart/README.md index fcd24a8..e092405 100644 --- a/examples/wrap-existing-chart/README.md +++ b/examples/wrap-existing-chart/README.md @@ -2,8 +2,8 @@ This is the most realistic use case for a Helm-based Nebari Software Pack. Instead of writing your own Deployment and Service templates, you add an -existing Helm chart as a dependency and create a NebariApp resource that points -to its service. +existing Helm chart as a dependency and point the NebariApp resource at its +service. **Key lesson: You don't rewrite the app - you just connect it to Nebari.** @@ -11,7 +11,7 @@ to its service. - Adding an upstream Helm chart as a `Chart.yaml` dependency - Overriding upstream values via your own `values.yaml` -- Creating a NebariApp that points to the upstream chart's service +- Pointing the NebariApp at the upstream chart's service from `values.yaml` - No custom Deployment or Service templates needed ## How It Works @@ -19,18 +19,25 @@ to its service. ``` Chart.yaml dependencies: + - name: nebari-app # Official chart that provides the NebariApp template + repository: oci://quay.io/nebari/charts - name: podinfo # Upstream chart handles pods + services version: 6.10.1 repository: oci://ghcr.io/stefanprodan/charts +values.yaml + nebariapp: # NebariApp spec: points to podinfo's service + podinfo: # Overrides passed to the podinfo chart + templates/ - nebariapp.yaml # Points to podinfo's service -> Nebari routes to it + nebariapp.yaml # Short include of the nebari-app template (no deployment.yaml!) # Podinfo chart handles this (no service.yaml!) # Podinfo chart handles this ``` -The only template you write is `nebariapp.yaml`. Everything else comes from the -upstream chart. +The only template you write is a short `nebariapp.yaml` that calls the +[`nebari-app`](https://github.com/nebari-dev/nebari-operator/tree/main/charts/nebari-app) +template. Everything else comes from the upstream chart or `values.yaml`. ## Deploying to Nebari @@ -110,10 +117,10 @@ kubectl port-forward svc/test-wrap-podinfo 9898:9898 | File | Purpose | |------|---------| -| `chart/Chart.yaml` | Helm chart metadata with podinfo dependency | +| `chart/Chart.yaml` | Helm chart metadata with podinfo and nebari-app dependencies | | `chart/values.yaml` | NebariApp config + podinfo overrides | | `chart/templates/_helpers.tpl` | Name, label, and selector helpers | -| `chart/templates/nebariapp.yaml` | NebariApp CRD pointing to podinfo's service | +| `chart/templates/nebariapp.yaml` | Renders the NebariApp via nebari-app | | `chart/templates/NOTES.txt` | Post-install instructions | ## Adapting for Your Own Chart