Skip to content

feat: bundle Deno binary into the operator image - #13

Open
dmmordvi wants to merge 3 commits into
mainfrom
feat/embed-deno-bin
Open

feat: bundle Deno binary into the operator image#13
dmmordvi wants to merge 3 commits into
mainfrom
feat/embed-deno-bin

Conversation

@dmmordvi

@dmmordvi dmmordvi commented Jul 31, 2026

Copy link
Copy Markdown

Summary

TypeScript charts need a Deno binary. Today nelm downloads it from github.com on the first TS render, which needs egress from every pod and a writable cache dir. The operator image now ships Deno at /usr/local/bin/deno and points nelm at it via NELM_DENO_BINARY_PATH, mirroring what nelm itself does for its release binaries in werf/nelm#675.

Key changes

  • Deno in the image — a denoland/deno:bin-${DENO_VERSION} stage provides just the binary, and COPY --from picks the right one per target platform, so no arch mapping, unzip, or checksum handling is needed. Integrity comes from the image digest.
  • Base image moves to gcr.io/distroless/cc-debian12:nonroot — Deno is dynamically linked against glibc (libc, libm, libgcc_s, libpthread, libdl), which distroless/static does not provide.
  • Wiring--deno-binary-path now falls back to $NELM_DENO_BINARY_PATH before nelm's runtime download, following the existing NELM_RELEASE_STORAGE_SQL_CONNECTION pattern. The flag still wins, so running manager outside this image behaves as before. The path was already plumbed into common.TypeScriptOptions for plan and install.
  • PLATFORMS narrowed to linux/arm64,linux/amd64 — Deno publishes no s390x/ppc64le linux builds, so make docker-buildx with the old default would fail on the COPY --from=deno step.

Why

TypeScript rendering currently fails in air-gapped clusters and in any environment without egress to github.com, and otherwise costs a ~45 MiB download per cold pod. Shipping the binary makes the image self-contained and removes a network dependency from the reconcile path.

Verification

  • Built the image and ran it: deno --version from the image reports 2.7.1 (aarch64-unknown-linux-gnu), and manager --help starts as nonroot under --read-only --tmpfs /tmp.
  • Cross-built for linux/amd64: the bundled binary reports x86_64-unknown-linux-gnu, confirming the Deno stage resolves per target platform and is not caught by the sed rewrite in docker-buildx, which only patches the first FROM.
  • Not run: an actual TypeScript chart render against a live cluster.

Review focus / risks

  • Image size grows by roughly 130 MB uncompressed (Deno 108 MB plus the cc base over static), to ~250 MB. Every user pays this, including those who never deploy a TypeScript chart. An init container copying Deno into a shared emptyDir would keep the default image thin at the cost of chart complexity — worth deciding now if that tradeoff is unacceptable.
  • The base image change affects all users, not just TS ones: distroless/cc carries glibc and a slightly larger CVE surface than distroless/static.
  • Runtime behavior relies on /tmp being writable, since Deno's DENO_DIR resolves to $HOME/.cache/deno and HOME=/tmp. The chart already mounts an emptyDir there, so readOnlyRootFilesystem: true is fine — but a custom deployment dropping that volume would break TS rendering.

TypeScript charts need Deno, which nelm otherwise downloads from GitHub
on
first render. That needs egress and a writable cache in every pod, so
the
image now ships the binary and points nelm at it.

Deno is dynamically linked against glibc, so the final image moves from
distroless/static to distroless/cc. Multi-arch builds are limited to
amd64/arm64 because Deno publishes no other linux builds.

Signed-off-by: Dmitry Mordvinov <dmitry.mordvinov@flant.com>
@dmmordvi
dmmordvi force-pushed the feat/embed-deno-bin branch from ce13ccd to 9e6ea87 Compare July 31, 2026 18:38
Signed-off-by: Dmitry Mordvinov <dmitry.mordvinov@flant.com>
@dmmordvi
dmmordvi marked this pull request as ready for review August 1, 2026 11:41
@dmmordvi
dmmordvi requested a review from ilya-lesikov August 1, 2026 11:41
Signed-off-by: Dmitry Mordvinov <dmitry.mordvinov@flant.com>
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