Skip to content

Build a runner image

An execution environment is registered by digest, so before you can create one you need an image that contains the released Helmhive runner plus everything your repositories’ commands require. This is usually done by your operator or a platform engineer; the console only ever sees the resulting digest.

Jobs run in a fresh sandbox with no network access from commands. Repository input and output are brokered by Helmhive, but a command such as pnpm install --frozen-lockfile or pip install cannot reach a package registry. An install command in a service policy therefore succeeds only if the image already holds what it needs: a warmed package-manager cache, vendored modules, or pre-installed system packages. Plan the image around the commands you intend to approve.

Start from the released runner image by digest, add packages as root, and return to the runner user:

1.7
ARG HELMHIVE_RUNNER_IMAGE
FROM ${HELMHIVE_RUNNER_IMAGE}
USER root
# Add the exact packages the assigned services need. Pin versions according to your own
# supply-chain policy. Warm any package caches the approved install command relies on.
RUN apt-get update \
&& apt-get install --yes --no-install-recommends jq \
&& rm -rf /var/lib/apt/lists/*
USER runner

Build and publish it through your reviewed CI, never by hand on a runner host, and never install packages dynamically during a job.

Terminal window
docker build --build-arg HELMHIVE_RUNNER_IMAGE='<runner-image>@sha256:<digest>' \
-t registry.example.test/team/runner:build-123 .
docker push registry.example.test/team/runner:build-123
docker inspect --format '{{index .RepoDigests 0}}' registry.example.test/team/runner:build-123

The last command prints the immutable reference ending in @sha256:…. That, the platform, and the list of executables you guarantee are what you enter in the console. Mutable tags are rejected.

Create an execution environment with the digest, then register a runner in the console and have your operator deploy it from the same image.