Image Policy¶
Resolution order¶
The executor resolves the requested image in this order:
- the job's
image:field, ifJEBALLTO_ALLOW_JOB_IMAGE_OVERRIDE=true CUSTOM_ENV_CI_JOB_IMAGEJEBALLTO_DEFAULT_IMAGE
If nothing resolves to an image, prepare fails.
Required image contents¶
The image must boot a macOS VM that provides these tools in PATH:
bashgitgitlab-runner
Before running job commands, the executor prepends common macOS tool locations to the remote shell PATH:
/opt/homebrew/bin:/usr/local/bin
That means tools installed by Homebrew or local admin scripts can be found even when the SSH login shell starts with a minimal PATH. The tools still need to exist in the image.
Allowing job-level overrides safely¶
Job-level image selection is flexible, but it can also widen your blast radius. A good production baseline is:
- keep
JEBALLTO_ALLOW_JOB_IMAGE_OVERRIDE=true - define
JEBALLTO_IMAGE_ALLOWLIST - restrict allowed images to your registry namespace
Example:
export JEBALLTO_IMAGE_ALLOWLIST='ghcr.io/myorg/*,registry.internal/ci/*'
When to prefer a default image¶
Use JEBALLTO_DEFAULT_IMAGE when:
- most jobs should land on the same image
- you want a stable first rollout
- your runners are operated by a central team
Use per-job images when:
- different pipelines need materially different Xcode or SDK stacks
- the image catalog is curated and guarded by an allowlist
Common image problems¶
- image typo: fails during resolution or pull
- image exists but lacks
gitlab-runner: toolchain probe fails - image boots but SSH credentials do not match executor settings: prepare fails late
- image requests too many resources for the host: provisioning slows or fails under load