Skip to main content
Workspace images let you build custom container runtimes with your project’s dependencies pre-installed. Instead of installing tools on every task startup, you bake them into an image once and every new task launches with everything ready. There are two workflows: manual (paste a Dockerfile into settings) and repo-managed (commit a Dockerfile in your repo and let Whim rebuild automatically as branches change).

Choose a workflow

Manual workspace image

Paste a full Dockerfile into Settings > Images. Whim injects RUNNER_COMPAT_REF for you at build time. Best for simple, project-wide customizations.

Repo-managed branch images

Add image config to whim.json or package.json, commit the Dockerfile in your repo, and let Whim build branch-specific images automatically. Best for projects with branch-dependent dependencies.

Manual setup

1

Open Workspace Settings

Navigate to Workspace Settings > Images.
2

Create a new image

Click New Image and paste a full Dockerfile. Manual builds use the same Dockerfile format as repo-managed builds (see Dockerfile format rules below).
3

Watch the build log

Builds run remotely. If something fails, expand the image and check the Build Log tab for details.
4

Activate the ready image

A built image does nothing until you activate it. Activation also rebuilds the warm reserve pool for that image so new tasks start fast.

Manual Dockerfile example

ARG RUNNER_COMPAT_REF
FROM ${RUNNER_COMPAT_REF}

USER root
RUN apt-get update && apt-get install -y git ripgrep
RUN python3 -m pip install --no-cache-dir poetry ruff
USER node
Manual builds use a Dockerfile-only build context. Plain COPY/ADD from local files is not supported, but inline heredoc COPY/ADD and multi-stage COPY --from=... work fine.

Repo-managed setup

Add image configuration to your repository root. Whim checks whim.json first, then falls back to the whim.image field in package.json.

Configuration file

whim.json
{
  "image": {
    "dockerfile": "Dockerfile.whim",
    "context": ".",
    "stagedFiles": ["package.json", "pnpm-lock.yaml"],
    "buildSecrets": ["NPM_TOKEN"]
  }
}
FieldDescription
dockerfilePath to the Dockerfile relative to repo root
contextBuild context directory (usually ".")
stagedFilesFiles explicitly available for COPY/ADD during build
buildSecretsWorkspace environment variable names to expose as build secrets

Repo-managed Dockerfile example

Dockerfile.whim
ARG RUNNER_COMPAT_REF
FROM ${RUNNER_COMPAT_REF}

COPY package.json pnpm-lock.yaml /app/
RUN cd /app && pnpm install --frozen-lockfile

USER root
RUN python3 -m pip install --no-cache-dir poetry ruff
USER node

Enable branch tracking

After committing the config and Dockerfile, go to Settings > Images and track the branch. The default branch is added automatically. Non-default branches only get matching-config images after you explicitly track them.

Dockerfile format rules

These rules apply to both manual and repo-managed Dockerfiles:
  • Must start with ARG RUNNER_COMPAT_REF and the final stage must use FROM ${RUNNER_COMPAT_REF} (or $RUNNER_COMPAT_REF). Whim resolves this variable to the workspace-compatible runner image at build time.
  • Manual builds use a Dockerfile-only context — no local files are available. Use inline heredoc COPY/ADD or COPY --from=... from earlier build stages.
  • Repo-managed builds can only COPY/ADD files explicitly listed in stagedFiles. Other repo files are not available in the build context.
  • Image freshness is determined by hashing the normalized image config, Dockerfile content, and the contents of declared stagedFiles. The entire repository is not hashed.
  • Multi-stage builds work fine as long as you only use COPY --from=... to copy between stages.
  • Build secrets referenced in buildSecrets must already exist as workspace environment variables with the same names.

Build process and status

When you trigger a build (manually or via a branch push), the image goes through these statuses:
StatusDescription
BuildingDocker build is running remotely
ReadyBuild succeeded, image is available for activation
FailedBuild failed — check the build log for details
After a successful build, Whim also validates runtime compatibility to ensure the image works correctly with the task runtime. An image must be both Ready and Compatible before it can be activated. Each image displays:
  • Image ID — auto-generated identifier (e.g., IMG-1, IMG-42) or a custom name you provide
  • Image size — the container image size
  • Creation timestamp — when the build was initiated

Activating and deactivating images

A built image does nothing until you activate it. Only one image can be active per workspace at a time (or per tracked branch for repo-managed workflows).
  • Activate — Sets the image as active and triggers the warm reserve pool to rebuild with the new image. Only images with Ready status and Compatible runtime can be activated.
  • Deactivate — Removes the active image. Tasks will fall back to the default Whim runtime. You can deactivate by workflow type (manual or repo-managed).
Only team admins can build, activate, delete, or track workspace images.

Warm reserve pools

Warm reserves are pre-created, suspended machines running your custom image. When a task starts, Whim claims a reserve machine and resumes it instantly instead of building a new container from scratch. This dramatically reduces task startup time.

How it works

  1. Whim creates machines with your custom image and starts them to initialize
  2. Once initialized, the machines are suspended — they consume no compute but stay ready
  3. When a task starts, Whim claims an available machine, resumes it, and injects the task’s configuration
  4. If no reserve machine is available, Whim falls back to creating a new container (slower startup)

Reserve targets

Each tracked branch has a reserve target — the number of warm machines to maintain. You can adjust this from 0 to 20 per branch. Default branch reserves are included in your plan at no extra cost:
PlanIncluded reserves
Free3 machines
Pro5 machines
Max10 machines
Machines above the included amount, and all non-default branch reserves, consume compute units.

Reserve costs

Each reserve machine costs 3 CU per week. Costs are prorated — if you add a tracked branch mid-billing period, you’re only charged for the remaining time.
Reserve targetWeekly CU cost
1 machine3 CU
5 machines15 CU
10 machines30 CU
20 machines60 CU
Warm starts are best-effort. Even with reserves configured, the pool can be empty or unhealthy. In that case, Whim creates a new container and startup may be slower.

Branch tracking and reserves

For repo-managed workflows, branch tracking controls which branches get dedicated images and warm reserves.
  • Default branch — Automatically tracked. Uses plan-included reserve capacity at no extra CU cost (up to the plan limit).
  • Non-default branches — Must be explicitly tracked from Settings > Images. Reserve machines for non-default branches consume CU.
  • Fallback behavior — If a tracked branch doesn’t have a ready image yet (build still in progress), tasks may launch with a similar available image or the default Whim runtime.
  • Stale cleanup — Branches with no task activity for 14 days are automatically untracked to free up reserve capacity.

Things to be aware of

Builds are asynchronous

A tracked branch can exist before its image is ready. During the build window, tasks may launch with a similar image or the default runtime.

Warm starts are best-effort

Even with a custom image and reserves configured, the warm reserve can be empty or unhealthy. Whim falls back to creating a new container, which means slower startup.

Mixing workflows

Manual images and repo-managed images can coexist in the same workspace. However, behavior is easier to reason about if you standardize on one workflow.

Admin-only

Only team admins can build, activate, delete, or manage tracked branches for workspace images.