Customizing a Single-Node Deployment#

This guide explains which files to edit and which auplc-installer command to re-run after you change a single-node install—for example adding a course, changing auth, or rebuilding an image.

The behavior described here matches the installer on the repository develop branch (auplc_installer/).

See also

For the initial install path, see Quick Start and Single-Node Deployment.

Two Configuration Layers#

Helm deploys JupyterHub with two values files merged together:

File

Who owns it

Purpose

runtime/values.yaml

You (checked into git)

Site configuration: auth, ingress, teams, resource catalog, quotas, storage, and any new courses you add.

runtime/values.local.yaml

Installer (auto-generated)

Machine-specific overlay: detected GPU SKU, gfx-tagged image references for GPU resources, and optional course-selection filtering.

The installer writes runtime/values.local.yaml during install and runtime commands. Its header marks it as auto-generated:

# Auto-generated by auplc-installer.
# Detected SKU keys : strix
# Product names    : AMD_Radeon_890M_Graphics
# Primary gfx tag  : gfx1150
# Course selection : all (default)
# Regenerated on install/upgrade.

Do not treat values.local.yaml as the place to add a new course or change auth. Edit runtime/values.yaml for intentional site changes. The installer regenerates the local overlay on install, rt install, rt upgrade, and rt reinstall—hand-edits there will be lost.

Helm merge order (later files win on conflicting keys):

runtime/values.yaml  +  runtime/values.local.yaml  →  deployed release

Quick Reference: What To Run After a Change#

You changed…

Edit

Re-run

Hub settings, auth, ingress, storage class, teams, quotas, spawn options

runtime/values.yaml

./auplc-installer rt upgrade

Hub Python code or Hub Dockerfile

runtime/hub/…, dockerfiles/Hub/…

./auplc-installer img build hub then ./auplc-installer rt reinstall

An existing course image (Dockerfile / course content)

dockerfiles/Courses/…

./auplc-installer img build <target> then ./auplc-installer rt reinstall

Which existing courses are visible / pulled (subset)

— (use CLI flag)

./auplc-installer rt upgrade --courses=… (or full ./auplc-installer install --courses=… if you also need images/K3s)

Image registry or tag coordinates

CLI flags

./auplc-installer rt upgrade --image-registry=… --image-tag=…

Add a brand-new course (new spawn option)

See Adding a new course below

./auplc-installer img build then ./auplc-installer rt reinstall

K3s, device plugin, or full stack from scratch

./auplc-installer install

Preview a full install plan without touching the cluster:

./auplc-installer install --dry-run

(--dry-run applies to install only, not to rt upgrade or rt reinstall.)

What Each Runtime Command Does#

Understanding the split between values changes and image changes avoids unnecessary full reinstalls.

rt upgrade — config / overlay refresh#

Use when you changed runtime/values.yaml, want to refresh GPU detection, change --courses=, or update --image-registry / --image-tag.

On every run it:

  1. Re-detects GPU SKUs on the node

  2. Regenerates runtime/values.local.yaml

  3. Runs helm upgrade with -f runtime/values.yaml -f runtime/values.local.yaml

It does not rebuild or pull container images.

If you run rt upgrade without --courses=, the installer reads the # Course selection : line from the existing overlay and preserves your previous course subset (for example basic). Pass --courses= explicitly to change it.

rt reinstall — pick up new images#

Use after ./auplc-installer img build or when pods must restart against freshly built local images.

It runs helm uninstall, then the same path as rt install (regenerate overlay + helm install + wait for deployments).

install — full stack#

Use for first-time deployment or when you need K3s, the ROCm device plugin, image pull/build stages, and Hub deploy together. Re-running install on an existing node is heavier than rt upgrade or rt reinstall.

Changing Existing Settings (No New Course)#

Example: switch auth mode or edit team mappings#

  1. Edit runtime/values.yaml (for example custom.authMode, custom.teams.mapping).

  2. Apply:

    ./auplc-installer rt upgrade
    

Example: rebuild after a Dockerfile change#

If you changed the Hub or a course image but not values.yaml:

./auplc-installer img build cv          # Makefile targets: hub, cv, dl, llm, physim, base-rocm, base-cpu, …
./auplc-installer rt reinstall

img build alone does not redeploy; rt reinstall removes and redeploys the Helm release so pods pick up the new local images.

Example: install only base CPU + GPU environments#

./auplc-installer rt upgrade --courses=basic

Valid course keys (from auplc_installer/catalog.py): cpu, gpu, Course-CV, Course-DL, Course-LLM, Course-PhySim. Presets: all, basic (cpu + gpu), none (Hub only).

Do not only edit values.local.yaml to hide courses—the overlay is regenerated from the installer catalog and your --courses= selection.

Adding a New Course#

Adding a spawn-time environment (for example Course-MyLab) touches several layers. This is a developer / site operator task; the installer does not discover new courses automatically.

runtime/values.yaml includes an inline Course Management Guide at the top of the file with the same three-step pattern (images → requirements → teams).

1. Course image#

  • Add a Dockerfile under dockerfiles/Courses/ (follow an existing course such as DL or CV).

  • Add a make target in dockerfiles/Makefile (for example my-lab).

Build and verify:

./auplc-installer img build my-lab
# or: make -C dockerfiles my-lab GPU_TARGET=gfx1150

2. Installer catalog (pull / build / TUI course picker)#

Add an entry to COURSE_CATALOG in auplc_installer/catalog.py and extend BASE_TEAM_MAPPING if new groups should see the course.

Without this step, ./auplc-installer install --courses=…, img build, and the TUI course picker will not know your course key.

3. Overlay mapping (GPU courses only)#

For GPU-tagged courses, also add the resource key and image basename to _RESOURCE_IMAGE_BASE in auplc_installer/overlay.py. The overlay emits gfx-suffixed image lines only for keys listed there (gpu, Course-CV, …).

CPU-only resources (like the built-in cpu course) keep plain image tags in values.yaml and are not rewritten by the overlay.

4. Hub resource catalog#

Edit runtime/values.yaml under custom.resources:

  • images — image reference (placeholder tag is fine; the overlay rewrites GPU course tags locally)

  • metadata — display name, description, acceleratorKeys, optional launchMode

  • requirements — CPU/RAM/GPU spawn requirements if needed

Add the course key to custom.teams.mapping for every group that should see it in the spawn UI.

See Configuration Reference for field details.

5. Deploy#

After images exist locally (or in your registry):

./auplc-installer rt reinstall

Run a full ./auplc-installer install only if you also changed K3s-level settings or need to pull/build images again.

6. Verify#

kubectl get pods -n jupyterhub

Open the Hub spawn page and confirm the new resource appears for a user in the right group.

Understanding values.local.yaml#

The local overlay typically sets:

  • custom.accelerators.<sku>.nodeSelector (and optional HSA_OVERRIDE_GFX_VERSION) from detected GPU product names

  • custom.resources.images for GPU resources only, with registry tags including -<gfxNNNN> suffixes

  • custom.resources.metadata.<resource>.acceleratorKeys aligned with detected SKUs

  • Filtered custom.teams.mapping when install or upgrade used --courses= other than all

If you need different image tags on this machine, prefer CLI flags:

./auplc-installer rt upgrade --image-tag=develop --image-registry=ghcr.io/myfork

rather than hand-editing the overlay.

Common Mistakes#

Mistake

Better approach

Adding a course only in values.local.yaml

Add to values.yaml, catalog.py, Dockerfile, and (for GPU courses) overlay.py; redeploy with rt reinstall

Running rt upgrade after an image rebuild

Use rt reinstall so pods restart with new images

Running full install for every values.yaml tweak

Use rt upgrade unless you also need K3s, image pull/build, or device-plugin deploy

Editing values.local.yaml and expecting it to persist

Change values.yaml or re-run rt upgrade / install with the flags you need

Expecting rt upgrade to preserve a hand-edited course list in the overlay

Pass --courses= explicitly, or rely on the preserved # Course selection header from the previous install