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
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

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
13 changes: 9 additions & 4 deletions examples/basic-nginx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

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