Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
21be5c8
docs: add Docusaurus config files
andrewfulton9 May 26, 2026
008f8a2
docs: add Nebari theming and static assets
andrewfulton9 May 26, 2026
d42eef4
docs: add stub content pages
andrewfulton9 May 26, 2026
6eeb102
docs: add docs/README.md with local dev instructions
andrewfulton9 May 26, 2026
8900b44
docs: add yarn.lock
andrewfulton9 May 26, 2026
01d3b6c
chore: ignore docs/node_modules
andrewfulton9 May 26, 2026
9697b9b
add docs paths to .gitignore
andrewfulton9 May 26, 2026
dd3dc05
docs: remove nix-specific instructions from README
andrewfulton9 May 26, 2026
16aa345
chore: add generate-docs target to Makefile
andrewfulton9 Jun 4, 2026
1ba3bfa
docs: annotate values.yaml with helm-docs comments
andrewfulton9 Jun 4, 2026
71516cd
docs: add helm-docs template for values.md generation
andrewfulton9 Jun 4, 2026
697c8db
docs: add helm-docs generate script and generated values.md
andrewfulton9 Jun 4, 2026
55e43c0
docs: fill in deployment/index.md
andrewfulton9 Jun 4, 2026
a50453d
docs: fill in deployment/deploy.md with install guide
andrewfulton9 Jun 4, 2026
9885bb2
docs: fill in deployment/architecture.md with diagram and resource table
andrewfulton9 Jun 4, 2026
27a7d47
ci: add workflow to check values.md stays in sync with values.yaml
andrewfulton9 Jun 4, 2026
c644022
docs: fill in introduction.mdx with overview, features, and at-a-glan…
andrewfulton9 Jun 4, 2026
3bddc4c
docs: fill in deploy.md prerequisites and what the pack deploys
andrewfulton9 Jun 4, 2026
80a2bc3
docs: improve language
andrewfulton9 Jun 4, 2026
39f9e2f
add local dev loop section
andrewfulton9 Jun 4, 2026
7890bca
docs: restructure deploy.md to match data-science-pack pattern
andrewfulton9 Jun 4, 2026
e4a1803
rework structure
andrewfulton9 Jun 4, 2026
0163253
docs: fix deploy.md local dev section — add Nebi UI URL and Tilt rele…
andrewfulton9 Jun 4, 2026
6fda6c2
revert: remove ADMIN_USERNAME/ADMIN_PASSWORD env vars added in rework…
andrewfulton9 Jun 4, 2026
11a2347
add deploy-with-data-science-pack page
andrewfulton9 Jun 9, 2026
90f8e2e
fix index number for templated page
andrewfulton9 Jun 9, 2026
6b93999
remove section
andrewfulton9 Jun 9, 2026
4350c9e
rename go template for creating values.md
andrewfulton9 Jun 9, 2026
02eea94
update troubleshooting guide
andrewfulton9 Jun 9, 2026
3153461
remove architecture page for now
andrewfulton9 Jun 9, 2026
6f1caa8
remove architecture, add with data science pack
andrewfulton9 Jun 9, 2026
ff1dd53
update values template
andrewfulton9 Jun 9, 2026
440e943
move values generation instructions from template to readme
andrewfulton9 Jun 9, 2026
7fe88a9
update generation
andrewfulton9 Jun 9, 2026
324804c
Merge remote-tracking branch 'upstream/main' into docs/admin_docs
andrewfulton9 Jun 9, 2026
dc9e6ca
fix workflow
andrewfulton9 Jun 9, 2026
a8a4401
Merge remote-tracking branch 'upstream/main' into docs/admin_docs_merge
andrewfulton9 Jun 15, 2026
3712f95
update sidebar
andrewfulton9 Jun 15, 2026
61b0451
remove js files
andrewfulton9 Jun 15, 2026
7a36b9b
Merge remote-tracking branch 'upstream/main' into docs/admin_docs
andrewfulton9 Jun 15, 2026
89fada2
fix broken link
andrewfulton9 Jun 15, 2026
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
33 changes: 33 additions & 0 deletions .github/workflows/docs-values-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Check values.md is up to date

on:
pull_request:
paths:
- 'values.yaml'
- 'docs/docs/deployment/values.md'
- 'docs/helm-docs.gotmpl'

jobs:
check-values-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install helm-docs
run: |
wget -q -O helm-docs.tar.gz \
https://github.com/norwoodj/helm-docs/releases/download/v1.14.2/helm-docs_1.14.2_Linux_x86_64.tar.gz
tar -xzf helm-docs.tar.gz helm-docs
sudo mv helm-docs /usr/local/bin/helm-docs

- name: Regenerate values.md
run: |
helm-docs \
--chart-search-root=. \
--template-files=docs/values.md.gotmpl \
--output-file=docs/docs/deployment/values.md

- name: Fail if values.md is out of sync
run: |
git diff --exit-code docs/docs/deployment/values.md || \
(echo "❌ values.md is out of sync. Run 'make generate-docs' and commit the result." && exit 1)
26 changes: 26 additions & 0 deletions .helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

# Docs site (not part of the Helm chart)
docs/
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Minimal Makefile for local development
# Only two commands needed - Tilt handles everything else via its UI

.PHONY: up down
.PHONY: up down generate-docs

# Start local development environment
# - ctlptl apply is idempotent (creates cluster only if not exists)
Expand All @@ -15,3 +15,7 @@ down:
-tilt down
-pkill -f "tilt up" 2>/dev/null || true
ctlptl delete -f ctlptl-config.yaml

# Generate docs/docs/deployment/values.md from annotated values.yaml
generate-docs:
yarn --cwd docs generate
253 changes: 253 additions & 0 deletions docs/docs/deployment/deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
---
title: Deploy the pack
description: Step-by-step instructions for deploying the Nebari Nebi Pack.
sidebar_position: 1
---

# Deploy the pack

This guide is for **operators** installing the pack on a Kubernetes
cluster. End users connecting to an already-deployed cluster should read
[Use the pack](../user-guide/use) instead.

:::note[Defaults reflect chart v0.1.0-alpha.4]

Image tags and other defaults cited below match
[`Chart.yaml`](https://github.com/nebari-dev/nebari-nebi-pack/blob/main/Chart.yaml)
and [`values.yaml`](https://github.com/nebari-dev/nebari-nebi-pack/blob/main/values.yaml)
on `main`. Check the repo for the latest pinned versions before copying
examples verbatim.

:::

The pack deploys:

- **Nebi server** — a single-pod Deployment running `--mode=both` (API + background worker combined). Image: `quay.io/nebari/nebi`. Listens on port 8460.
- **PostgreSQL 16** — an embedded StatefulSet for application state and workspace metadata. 10 Gi persistent storage.
- **ClusterIP Service** — exposes the Nebi server on port 80 within the cluster.
- **Environments PVC** — 20 Gi RWO volume mounted at `/app/data/environments` for pixi workspace files.
- **Secret** — JWT signing key and PostgreSQL password, created once by a PreSync Job and never overwritten on upgrade.
- **NebariApp** *(Nebari clusters only)* — configures Envoy Gateway routing and provisions a Keycloak OIDC client automatically.
- **ServiceAccount** — bound to the Nebi Deployment.

## Prerequisites

| Requirement | Details |
|---|---|
| Kubernetes ≥ 1.27 | Any CNCF-conformant cluster; [k3d](https://k3d.io/) works for local dev |
| Helm ≥ 3.12 | |
| `nebari-operator` | Required when `nebariapp.enabled: true` (Nebari clusters only) |
| Persistent storage | Default StorageClass with RWO support; ~30 Gi total |
| ArgoCD | Required for the GitOps path only |

## Standalone install (no Nebari)

Use this path for local dev or clusters without `nebari-operator`. Skips
the NebariApp routing layer entirely. You are responsible for exposing
the service and handling authentication.

### From source

```bash
git clone https://github.com/nebari-dev/nebari-nebi-pack.git
cd nebari-nebi-pack

helm install nebi-pack . \
--namespace nebi \
--create-namespace \
--set nebariapp.enabled=false
```

Expose the service with an Ingress:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nebi
namespace: nebi
spec:
rules:
- host: nebi.your-cluster.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nebi-pack-nebari-nebi-pack
port:
number: 80
```

### Local dev loop (Tilt + k3d)

The [repo](https://github.com/nebari-dev/nebari-nebi-pack) ships a Tiltfile and `ctlptl-config.yaml` for an end-to-end
local dev loop. Prerequisites:
[Docker](https://docs.docker.com/get-docker/),
[ctlptl](https://github.com/tilt-dev/ctlptl),
[Tilt](https://docs.tilt.dev/install.html).

```bash
make up # creates the k3d cluster and starts Tilt
# Tilt UI: http://localhost:10350
# Nebi UI: http://localhost:8460 (Tilt auto-forwards this port)
make down # tear down cluster and Tilt
```

:::note
In the local dev loop, Tilt uses `nebi` as the Helm release name, so
resources are named `nebi-nebari-nebi-pack` (not `nebi-pack-nebari-nebi-pack`).
The `kubectl` commands in [Verifying the deployment](#verifying-the-deployment)
use the `nebi-pack` release name from the Helm/ArgoCD paths — adjust
accordingly if you are inspecting a Tilt-managed deployment.
:::



## Nebari install (ArgoCD + GitOps)

The recommended production deployment. The chart creates a `NebariApp`
resource that `nebari-operator` picks up to provision routing, TLS, and
Keycloak OIDC.

Save the following to `apps/nebi-pack.yaml` in your GitOps repo:

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nebi-pack
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/nebari-dev/nebari-nebi-pack.git
path: .
targetRevision: main
helm:
releaseName: nebi-pack
values: |
nebariapp:
hostname: nebi.your-cluster.example.com
destination:
server: https://kubernetes.default.svc
namespace: nebi
syncPolicy:
automated:
prune: true
selfHeal: true
managedNamespaceMetadata:
labels:
nebari.dev/managed: "true"
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
- SkipDryRunOnMissingResource=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
```

:::warning[`nebari.dev/managed: "true"` is required]

The `managedNamespaceMetadata` block applies the `nebari.dev/managed`
label to the namespace. **Without this label the nebari-operator will
silently ignore your NebariApp resource** — the hostname will return 404
and `kubectl describe nebariapp` will show no progress on conditions.

:::

**What happens on first sync:**

1. The PreSync Job runs before any other resources are applied. It creates a Kubernetes Secret containing a random JWT signing key and PostgreSQL password — only if the secret does not already exist.
2. The PostgreSQL StatefulSet starts and waits to become healthy.
3. The Nebi Deployment starts, connects to PostgreSQL, and begins serving on port 8460.
4. `nebari-operator` reconciles the `NebariApp` CRD, provisions a Keycloak OIDC client, and configures Envoy Gateway to enforce authentication.

The chart's PreSync hook handles secret creation idempotently — no manual
bootstrapping required.

## Configuration

Configuring the chart beyond the defaults — auth groups, OIDC, storage
size, resource limits, the landing page card — is covered in the
[values.yaml reference](./values.md).

## Verifying the deployment

Check that all pods are running:

```bash
kubectl get pods -n nebi
```

Expected output:

```
NAME READY STATUS RESTARTS AGE
nebi-pack-nebari-nebi-pack-<hash> 1/1 Running 0 2m
nebi-pack-nebari-nebi-pack-postgres-0 1/1 Running 0 2m
```

Check the health endpoint:

```bash
kubectl run nebi-probe --rm -it --image=curlimages/curl --restart=Never -- \
curl -sf http://nebi-pack-nebari-nebi-pack.nebi.svc.cluster.local/api/v1/health
```

Expected: `{"status":"healthy"}` with HTTP 200.

If `nebariapp.enabled`, check the NebariApp conditions:

```bash
kubectl get nebariapp -n nebi
kubectl describe nebariapp -n nebi
```

You want `RoutingReady`, `TLSReady`, and `AuthReady` all `True`.

## Upgrade

```bash
helm upgrade nebi-pack . \
--namespace nebi \
--reuse-values \
--set image.tag=sha-<new-tag>
```

The PreSync Job is idempotent — it skips secret creation if the secret
already exists.

## Uninstall

```bash
helm uninstall nebi-pack --namespace nebi
```

:::warning PVC retention
`helm uninstall` does **not** delete PersistentVolumeClaims. Environment
and database data is preserved. To permanently delete all data:

```bash
kubectl delete pvc -n nebi -l app.kubernetes.io/instance=nebi-pack
```
:::

## Operator troubleshooting

Recovery steps for common failures — pods not starting, NebariApp stuck
on conditions, secret bootstrap errors — live on the
[Troubleshoot](./troubleshoot.md) page.

## Next steps

- **End users** → [Use the pack](../user-guide/use.md) — log in and manage environments.
- **Full chart reference** → [values.yaml reference](./values.md) — every option with type, default, and description.
- **Upstream docs** → [Nebi](https://github.com/nebari-dev/nebi), [Pixi](https://pixi.sh).
23 changes: 23 additions & 0 deletions docs/docs/deployment/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: Deployment
description: Install and configure the Nebari Nebi Pack on a Kubernetes or Nebari cluster.
sidebar_position: 1
---

import DocCardList from '@theme/DocCardList';

# Deployment

The Nebi Pack is a Helm chart that deploys [Nebi](https://github.com/nebari-dev/nebi) — a team environment management server built on [Pixi](https://pixi.sh) — on a Nebari or plain Kubernetes cluster. This section covers everything an operator needs to install, configure, and maintain the pack.

## Prerequisites

| Requirement | Notes |
|---|---|
| Kubernetes ≥ 1.27 | Any CNCF-conformant cluster |
| Helm ≥ 3.12 | |
| `nebari-operator` | Required when `nebariapp.enabled: true` (Nebari clusters only) |
| A dedicated namespace | Recommended: `nebi` |
| Persistent storage | Default StorageClass with RWO support; ~30 Gi total (20 Gi environments + 10 Gi PostgreSQL) |

<DocCardList />
Loading
Loading