Skip to content

docs: add serverless Node.js example mounting a function via ConfigMap#139

Open
scotwells wants to merge 2 commits into
mainfrom
docs/serverless-js-configmap
Open

docs: add serverless Node.js example mounting a function via ConfigMap#139
scotwells wants to merge 2 commits into
mainfrom
docs/serverless-js-configmap

Conversation

@scotwells

@scotwells scotwells commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

What this delivers

A runnable example showing a serverless pattern on Datum compute: a generic Node.js runtime image with no application code baked in, where the function (index.js) is supplied at deploy time via a ConfigMap mounted at /app, and Node executes the mounted file. One image serves any function, and swapping the code is a ConfigMap edit + restart — no image rebuild or repush. It complements examples/hello-node/ (#132), which bakes the app into the image; this example pulls the app back out and delivers it as data.

How it works

The generic image is built once on the base-compat:latest runtime with an erofs rootfs. The Kraftfile's cmd points node at /app/index.js — a mounted path, not a baked one. The Workload mounts the js-function ConfigMap at /app, so the function arrives as a read-only rom in the microVM at boot. Editing the function and restarting recreates the instance against the new content.

The js-function ConfigMap is generated from index.js by a Kustomize configMapGenerator, so index.js is the single source of truth — there is no second, hand-maintained copy of the function to drift. disableNameSuffixHash: true keeps the name stable, since the Workload references the ConfigMap by name and is deployed out-of-band via datumctl (a content-hash suffix would break the mount and buys nothing here).

What's included

examples/serverless-js-configmap/, ready to deploy as-is:

  • Dockerfile — multi-stage build of the generic runtime: a scratch image carrying only the node interpreter and its musl/libgcc/libstdc++ shared libraries. No JS.
  • Kraftfilespec: v0.7, base-compat:latest, rootfs.format: erofs, cmd: ["/usr/bin/node", "/app/index.js"].
  • index.js — the function and single source of truth for the ConfigMap: a dependency-free Node stdlib HTTP service on $PORT (default 8080), with a versioned response and startup log so a code swap is observable.
  • kustomization.yaml — a configMapGenerator that builds the js-function ConfigMap from index.js (kubectl apply -k .).
  • workload.yaml — the Datum Workload mounting the ConfigMap at /app (port 8080, d1-standard-2, DFW, minReplicas: 1).
  • README.md — build + push, apply-ConfigMap (-k), deploy, validate, and the code-swap steps, plus the runtime/erofs/empty-env pitfalls.

Validation

Verified end to end on the ash-sore-hamster metro: the ConfigMap mounts as a read-only rom at /app (mount /dev/ukp_rom1 -> /app in the boot log), Node executes the mounted file (serverless-js: v1 listening on :8080), and editing only the function swapped the live response v1 -> v2 on the same image SHA — no rebuild. (The generator produces a byte-identical js-function ConfigMap, so this validation is unchanged by the Kustomize refactor.)

Dependency

The referenced ConfigMap/Secret delivery this relies on (base-compat:latest + erofs) is delivered by #129; this example is most useful once that lands.

🤖 Generated with Claude Code

Adds a runnable example demonstrating a serverless pattern on Datum compute:
a generic Node.js runtime image with no application code baked in, where the
function is supplied at deploy time via a ConfigMap mounted at /app. One image
serves any function, and swapping the code is a ConfigMap edit + restart with
no image rebuild.

Validated end to end on the ash-sore-hamster metro: the ConfigMap mounts as a
read-only rom at /app, Node executes the mounted file, and editing only the
ConfigMap swaps the running response (v1 -> v2) on the same image.

Relies on the referenced ConfigMap/Secret delivery from #129 (base-compat:latest
runtime + erofs rootfs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@scotwells scotwells added the documentation Improvements or additions to documentation label Jun 3, 2026
Replace the hand-written configmap.yaml with a Kustomize configMapGenerator so
index.js is the single source of truth -- no second embedded copy of the
function to drift. disableNameSuffixHash keeps the generated ConfigMap named
js-function, which the Workload references by name and deploys out-of-band via
datumctl (so a content-hash suffix would break the mount and buys nothing here).

Apply and swap now use `kubectl apply -k .`; README and the index.js header
updated accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
scotwells added a commit that referenced this pull request Jun 3, 2026
Redraw the data-flow diagram so all box lines are uniform width and the
file-listing columns align; drop ambiguous-width glyphs from inside the
boxes. Convert the dependency note, runtime requirement, #139 reference,
and env-capacity limitation to GitHub alert callouts (IMPORTANT/TIP/
WARNING).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant