Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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/

Expand All @@ -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/

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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 \
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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/ \
Expand All @@ -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/ \
Expand Down
107 changes: 82 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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/
Expand Down Expand Up @@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Helm" section of docs/nebariapp-crd-reference.md (and its copy in docs/site/src/content/docs/nebariapp-crd-reference.md) still shows the hand-written template, plus a values block with service.name: "" # Defaults to release fullname. That default is gone now: an empty name fails with spec.service.name is required. The README links to that page as the complete field reference, so readers get two contradicting recipes. We should replace both copies of that section with the nebari-app.nebariApp include shown here, or link to this section.


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
Expand Down Expand Up @@ -329,14 +371,17 @@ 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
- Conditional NebariApp template (`nebariapp.enabled` toggle)
- 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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
```

Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -859,9 +908,17 @@ naming convention (usually `<release>-<chart-name>`).
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
Expand Down
47 changes: 25 additions & 22 deletions docs/site/src/content/docs/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
```

Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions examples/auth-fastapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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 |
Expand Down
6 changes: 6 additions & 0 deletions examples/auth-fastapi/chart/Chart.lock
Original file line number Diff line number Diff line change
@@ -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"
6 changes: 5 additions & 1 deletion examples/auth-fastapi/chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Loading
Loading