Concepts
Last updated
This section explains the key concepts behind Nebari Software Packs and the deployment methods the template supports.
The NebariApp integration point #
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.
Deployment methods #
All three Kubernetes deployment methods are first-class in the template and in ArgoCD.
Plain YAML #
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 #
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 #
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.
Template examples #
The template repo ships five examples of increasing complexity.
Example 1: Vanilla YAML #
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.
Example 2: Kustomize (Nginx) #
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.
Example 3: Helm - Basic Pack (Nginx) #
The simplest possible Helm chart - nginx with a conditional NebariApp template and a
nebariapp.enabled toggle. Shows the standalone / Nebari mode switch.
Example 4: Helm - Auth-Aware FastAPI #
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) #
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.
Local development #
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.
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.
Pack metadata #
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.
Edit this page on GitHub