Skip to content

feat(spike): one eoAPI stack per workshop participant - #64

Merged
lhoupert merged 16 commits into
developmentseed:feat/k8sfrom
lhoupert:spike/per-user-stacks
Oct 2, 2026
Merged

lhoupert merged 16 commits into
developmentseed:feat/k8sfrom
lhoupert:spike/per-user-stacks

Conversation

@lhoupert

@lhoupert lhoupert commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Gives every workshop participant their own eoAPI stack in one pod: JupyterLab, pgstac, stac-fastapi behind stac-auth-proxy, titiler-pgstac, tipg, mock-oidc, STAC Browser and STAC Manager. Everything is reached through the Lab (/stac, /raster, /vector, /browser, /manager, /oidc), behind one password per Lab URL. Notebooks 00–08 follow a per-participant URL contract and run without errors. The chart (spike/chart, driven by spike/deploy.sh) keeps each participant's DB and work/ on volumes, allows egress only to DNS and public 80/443, pins amd64 images that CI publishes, and can pre-pull them. Its tests run on local kind (spike/checks/). The spike behind this design (every topic's checks, write-ups and screenshots) is on spike/per-user-stacks-evidence.

For reviewers: nothing has run on the real cluster yet. TLS, Calico enforcing the policy, kernel websockets through ingress-nginx, and fsGroup on Cinder volumes come next, in a rehearsal. The base is feat/k8s (#35).

Author attestation

  • I am a human, these are my changes, and I have reviewed and understood every change and can explain why each is correct.

AI-assisted: the spike, checks and evidence were written with Claude Code (a multi-agent workflow, then an independent skeptic re-run of every check); I reviewed the diff and the check results.

lhoupert and others added 5 commits October 2, 2026 09:12
workshop_setup.py gains endpoints(), to_browser(), show_links() and
collection_id(): server-side and browser-facing URLs come from env vars,
replacing the per-notebook .replace() heuristics. Notebooks use per-user
collection ids, and 9 notebook-02 points with no Sentinel-2 items are
dropped. Compose and the chart set the browser-facing variables.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Compose layout of a participant pod: the Lab owns the netns, every other
service joins it and binds 127.0.0.1. jupyter-server-proxy exposes each
service same-origin under /stac /raster /vector /browser /oidc /manager,
behind the Lab password. The DB image bakes the ecoregions and glad data.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
One Deployment per participant from the compose containers (DB as a
native sidecar), a credentials Secret kept across upgrades, one Ingress
for the Lab hosts and a NetworkPolicy admitting only the ingress
controller. No cluster-scoped objects.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
zero-to-jupyterhub 4.4.2 running the same participant stack as
singleuser extraContainers, with a static per-user password
authenticator. Kept to compare against the own chart.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Reproducible check scripts per topic (build, apis, auth, browser apps,
notebooks, footprint, both front doors, verify) and the evidence they
produced, including the skeptic re-run in evidence/verify.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

lhoupert and others added 10 commits October 2, 2026 09:54
The infrastructure section still described the shared CDK endpoints
(workshop-*.eoapi.dev), Binder and DB credentials handed out on the day.
It now describes the participant's own stack behind the Lab login, the
work/ folder that survives a restart, and the links cell at the end.
The outline lists chapters 6-8; also fixes the 4.3 heading and typos.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The own chart is the front door: it fits one password per Lab URL and
laptop API access, for the same amount of code. The z2jh variant stays
in commit 10aac1d; evidence/frontdoor-hub.md keeps the comparison.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…uperseded

Each run keeps results/<label>/analysis.txt, the numbers the sizing
cites. The raw samples stay in commit e3c0479 and run.sh regenerates
them. fix.md and verify.md describe the current stack.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
stac-browser and stac-manager always printed PASS, and the other images
had to be arm64. Now each image must match the host, except those two,
which are only published for amd64.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CI lint failed with 114 errors under spike/. The auth checks are
fragments run after common.py, so F821 is ignored there; the rest are
renamed variables, two lambdas turned into defs, two unused imports.
Notebook 03's filter line now fits on one line.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- A PVC per participant for the DB (PGDATA one level down, past
  lost+found) and one for /home/jovyan/work. A pod replacement no longer
  wipes the participant; removing them or the release deletes both.
- The NetworkPolicy now also limits egress: DNS, and 80/443 on public
  addresses. Lab terminals can no longer reach the API server, other
  namespaces or node IPs.
- The Lab and DB images come from <registry>/eoapi-workshop-{lab,db}:<tag>
  (`local` on kind); nodeSelector/tolerations pin the pods to the
  workshop pool, and prepull adds a DaemonSet that pulls every image.

The kind checks probe egress both ways (policy present, then deleted)
and write their persistence files under work/.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Pushes ghcr.io/<owner>/eoapi-workshop-{lab,db}:sha-<commit> on main and
feat/k8s, the tag spike/chart pins. Pull requests build without pushing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Context, namespace, image tag and the whole participant list are always
explicit; up uses --reset-values (a bare helm upgrade reuses the last
--set) and refuses to drop participants without REMOVE=1. creds prints
the CSV for the handout slips. down needs CONFIRM=<namespace> and only
uninstalls the release, never the namespace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Kind: frontdoor-own 61/0/0 (egress probed with and without the policy),
verify/own.sh 4/0/0 (data survives pod replacement), deploy.sh's guards.
Compose checks unchanged from verify.md except build's fixed arch check.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
It measured the own chart against z2jh; that choice is made. The evidence
keeps its numbers and points at commit e3c0479 for the script.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lhoupert
lhoupert marked this pull request as ready for review October 2, 2026 09:34
The PR keeps what the workshop runs on (chart, deploy.sh, images,
compose, CI, notebook fixes) and the chart's kind tests. The per-topic
checks, write-ups and screenshots (~11,800 lines) stay on branch
spike/per-user-stacks-evidence (commit d50c0ce); the README links it
and now carries the kind setup steps and the sizing numbers.

The persistence probe deletes its collection first: with PVCs, a
previous run's copy survives, and POST answered 409.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lhoupert
lhoupert merged commit abdc6c5 into developmentseed:feat/k8s Oct 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant