Skip to content

Concepts

Updated 3 min read

This section explains the key concepts behind Nebari Software Packs and the deployment methods the template supports.

Every software pack has exactly one integration point with the Nebari platform: the NebariApp custom resource. When you create a NebariApp, the nebari-operator watches for it and 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:

{{- 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
{{- end }}

With plain YAML or Kustomize, the NebariApp manifest is always present. When deploying standalone, skip that file or exclude it from your apply command.

All three Kubernetes deployment methods are first-class in the template and in ArgoCD.

The lowest barrier to entry. Your pack is a set of .yaml files - deployment.yaml, service.yaml, and nebariapp.yaml. Users run kubectl apply -f ..

Best for: packs with no configuration variability, or internal tools where simplicity trumps flexibility.

Kustomize overlays let you patch environment-specific values (hostname, auth settings, resource limits) on top of a shared base without duplicating the base manifests.

base/
kustomization.yaml
deployment.yaml
service.yaml
nebariapp.yaml
overlays/
dev/
kustomization.yaml
nebariapp-patch.yaml # dev hostname, no auth
production/
kustomization.yaml
nebariapp-patch.yaml # prod hostname, auth + groups

Best for: packs deployed to multiple environments with known configuration differences.

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.

# Chart.yaml - add the upstream chart as a dependency
dependencies:
- name: podinfo
version: 6.10.1
repository: oci://ghcr.io/stefanprodan/charts
# templates/nebariapp.yaml - the only template you write
{{- if .Values.nebariapp.enabled }}
apiVersion: reconcilers.nebari.dev/v1
kind: NebariApp
spec:
hostname: {{ .Values.nebariapp.hostname }}
service:
name: {{ .Release.Name }}-podinfo # upstream service name
port: 9898
{{- end }}

Best for: wrapping existing Helm charts and for packs with rich configuration needs.

The template repo ships five examples of increasing complexity.

Plain Kubernetes manifests. kubectl apply -f examples/vanilla-yaml/. No tooling beyond kubectl. The NebariApp sits alongside deployment.yaml and service.yaml as a peer file.

Same nginx app as the vanilla example, structured with Kustomize overlays for dev and production. Demonstrates patching hostname and auth settings per environment without duplicating the base.

The simplest possible Helm chart - nginx with a conditional NebariApp template and a nebariapp.enabled toggle. Shows the standalone / Nebari mode switch.

A custom Python app that reads the IdToken-* cookie set by Envoy Gateway after Keycloak authentication. The key snippet:

def get_id_token(request: Request) -> str | None:
for name, value in request.cookies.items():
if name.startswith("IdToken-"):
return value
return None

Shows how to extract and decode the JWT to get preferred_username, email, and groups.

Example 5: Helm - Wrapping an Existing Chart (Podinfo)

Section titled “Example 5: Helm - Wrapping an Existing Chart (Podinfo)”

This is the most realistic use case. Most Helm-based packs wrap existing software. You add the upstream chart as a dependency, override values, and add a NebariApp that points to the upstream service. You do not write a Deployment or Service of your own.

The dev/ directory provides a Makefile for local development with kind. Running any up-* target automatically creates a kind cluster with the full Nebari infrastructure stack - MetalLB, Envoy Gateway, cert-manager, Keycloak, and the nebari-operator.

Terminal window
cd dev
make up-vanilla # deploy vanilla YAML example
make up-kustomize # deploy kustomize example (dev overlay)
make up-basic # deploy Helm nginx example
make up-fastapi # deploy FastAPI Helm example (auth enabled)
make update-hosts # update /etc/hosts with NebariApp hostnames
make down # delete the kind cluster

The first make up-* run takes 5-10 minutes (cluster and infrastructure setup). Subsequent runs reuse the existing cluster and are fast.

Every tracked pack has a pack-metadata.yaml at its repo root. Key fields:

level: experimental # experimental | alpha | beta | ga
owner: github-username
nebariapp_integration: full # none | partial | full | na
scope:
standalone-supported: yes

The software pack dashboard aggregates these files and renders a single view of every tracked pack. See the Release Readiness page for the full field reference and the promotion checklist.