From 9e6ea877459ae603b83afac511c8a4028d900f1c Mon Sep 17 00:00:00 2001 From: Dmitry Mordvinov Date: Fri, 31 Jul 2026 20:57:26 +0300 Subject: [PATCH 1/3] feat: bundle Deno binary into the operator image 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 --- .github/workflows/lint.yml | 2 ++ Dockerfile | 12 ++++++++++-- Makefile | 16 +++++++++++++++- cmd/main.go | 6 +++++- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d3f5b7b..7195174 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,5 +25,7 @@ jobs: - name: Check linter configuration run: make lint-config + - name: Check bundled Deno version + run: make check-deno-version - name: Run linter run: make lint diff --git a/Dockerfile b/Dockerfile index d681b65..36e6406 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,6 @@ +# Must match nelm's denoVersion constant in pkg/ts/downloader.go, see `make check-deno-version`. +ARG DENO_VERSION=2.7.1 + FROM golang:1.25 AS builder ARG TARGETOS @@ -16,12 +19,17 @@ COPY internal/ internal/ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go -FROM gcr.io/distroless/static:nonroot +FROM denoland/deno:bin-${DENO_VERSION} AS deno + +# Deno is dynamically linked against glibc, so the final image cannot be distroless/static. +FROM gcr.io/distroless/cc-debian12:nonroot -ENV HOME=/tmp +ENV HOME=/tmp \ + NELM_DENO_BINARY_PATH=/usr/local/bin/deno WORKDIR / +COPY --from=deno /deno /usr/local/bin/deno COPY --from=builder /nelm-operator/manager . USER 65532:65532 diff --git a/Makefile b/Makefile index f1e34e9..960ce94 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,19 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes lint-config: golangci-lint ## Verify golangci-lint linter configuration "$(GOLANGCI_LINT)" config verify +.PHONY: check-deno-version +check-deno-version: ## Verify DENO_VERSION in Dockerfile matches the Deno version nelm expects + @go mod download github.com/werf/nelm + @image_version="$$(sed -n 's/^ARG DENO_VERSION=//p' Dockerfile)"; \ + nelm_version="$$(sed -n 's/^const denoVersion = "\(.*\)"$$/\1/p' "$$(go list -m -f '{{.Dir}}' github.com/werf/nelm)/pkg/ts/downloader.go")"; \ + if [ -z "$$image_version" ]; then echo "cannot read ARG DENO_VERSION from Dockerfile"; exit 1; fi; \ + if [ -z "$$nelm_version" ]; then echo "cannot read denoVersion from nelm's pkg/ts/downloader.go"; exit 1; fi; \ + if [ "$$image_version" != "$$nelm_version" ]; then \ + echo "Dockerfile bundles Deno $$image_version, but nelm expects $$nelm_version: update ARG DENO_VERSION"; \ + exit 1; \ + fi; \ + echo "Deno $$image_version matches nelm" + ##@ Build .PHONY: build @@ -136,7 +149,8 @@ docker-push: ## Push docker image with the manager. # - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ # - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) # To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le +# Limited to amd64/arm64: Deno, which the image bundles for TypeScript charts, publishes no other linux builds. +PLATFORMS ?= linux/arm64,linux/amd64 .PHONY: docker-buildx docker-buildx: ## Build and push docker image for the manager for cross-platform support # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile diff --git a/cmd/main.go b/cmd/main.go index 2b14ac2..b369891 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -82,7 +82,7 @@ func main() { flag.IntVar(&cfg.NetworkParallelism, "network-parallelism", 30, "Limit of network-related tasks to run in parallel per reconcile.") // TypeScript / Misc. - flag.StringVar(&cfg.DenoBinaryPath, "deno-binary-path", "", "Path to the Deno binary for TypeScript chart rendering.") + flag.StringVar(&cfg.DenoBinaryPath, "deno-binary-path", "", "Path to the Deno binary for TypeScript chart rendering. Falls back to $NELM_DENO_BINARY_PATH, then to downloading Deno at runtime.") flag.StringVar(&cfg.TempDir, "temp-dir", "", "Directory for temporary files.") // Logging. @@ -117,6 +117,10 @@ func main() { cfg.ReleaseStorageSQLConnection = v } + if v := os.Getenv("NELM_DENO_BINARY_PATH"); v != "" && cfg.DenoBinaryPath == "" { + cfg.DenoBinaryPath = v + } + cfg.MetricsCertDir = metricsCertDir cfg.MetricsCertName = metricsCertName cfg.MetricsCertKey = metricsCertKey From b38106e4422c6993bb7d44bc0f25982c8230f53f Mon Sep 17 00:00:00 2001 From: Dmitry Mordvinov Date: Sat, 1 Aug 2026 14:35:24 +0300 Subject: [PATCH 2/3] feat: remove unnecessary deno version check Signed-off-by: Dmitry Mordvinov --- .github/workflows/lint.yml | 2 -- Dockerfile | 1 - Makefile | 13 ------------- 3 files changed, 16 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7195174..d3f5b7b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,7 +25,5 @@ jobs: - name: Check linter configuration run: make lint-config - - name: Check bundled Deno version - run: make check-deno-version - name: Run linter run: make lint diff --git a/Dockerfile b/Dockerfile index 36e6406..f144ab5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,3 @@ -# Must match nelm's denoVersion constant in pkg/ts/downloader.go, see `make check-deno-version`. ARG DENO_VERSION=2.7.1 FROM golang:1.25 AS builder diff --git a/Makefile b/Makefile index 960ce94..cbf9f86 100644 --- a/Makefile +++ b/Makefile @@ -109,19 +109,6 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes lint-config: golangci-lint ## Verify golangci-lint linter configuration "$(GOLANGCI_LINT)" config verify -.PHONY: check-deno-version -check-deno-version: ## Verify DENO_VERSION in Dockerfile matches the Deno version nelm expects - @go mod download github.com/werf/nelm - @image_version="$$(sed -n 's/^ARG DENO_VERSION=//p' Dockerfile)"; \ - nelm_version="$$(sed -n 's/^const denoVersion = "\(.*\)"$$/\1/p' "$$(go list -m -f '{{.Dir}}' github.com/werf/nelm)/pkg/ts/downloader.go")"; \ - if [ -z "$$image_version" ]; then echo "cannot read ARG DENO_VERSION from Dockerfile"; exit 1; fi; \ - if [ -z "$$nelm_version" ]; then echo "cannot read denoVersion from nelm's pkg/ts/downloader.go"; exit 1; fi; \ - if [ "$$image_version" != "$$nelm_version" ]; then \ - echo "Dockerfile bundles Deno $$image_version, but nelm expects $$nelm_version: update ARG DENO_VERSION"; \ - exit 1; \ - fi; \ - echo "Deno $$image_version matches nelm" - ##@ Build .PHONY: build From c4ad85c6b72d39cab7030f3566d34ff074b2dec4 Mon Sep 17 00:00:00 2001 From: Dmitry Mordvinov Date: Sat, 1 Aug 2026 16:47:38 +0300 Subject: [PATCH 3/3] chore: bupm deno version Signed-off-by: Dmitry Mordvinov --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f144ab5..4537a3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG DENO_VERSION=2.7.1 +ARG DENO_VERSION=2.9.4 FROM golang:1.25 AS builder