Skip to main content

Providers

A provider determines where and how a Loom job executes — on your local machine's shell or inside a Docker container. Provider selection is automatic: if your job specifies an image, it runs in Docker; otherwise, it runs on the host.

Why providers matter

Provider selection changes four things about your job's execution environment:

ConcernHost providerDocker provider
IsolationNone — inherits your local process environmentProcess and filesystem isolation via containers
Available toolsWhatever is installed on your machineWhatever is in the container image
Environment variablesYour shell env + Loom variablesOnly Loom variables + image defaults
Failure debuggingFailures reference local paths and toolsFailures reference container paths; check Docker daemon first

Host jobs use local tooling without starting a container. Docker jobs use image-defined tooling, which reduces dependencies on the host environment. Results can still vary with source, image content and platform, variables, and external services.

How Loom selects a provider

Provider selection is per-job and automatic. The rule is:

Does the job have image:?Provider usedWhat happens
No (omitted or empty)HostJob runs directly in your local shell
Yes (non-empty string)DockerJob runs inside a container using the specified image

There is no manual provider override. If you want a job to run in Docker, set image:. If you want it on the host, remove image:.

The provider name is available at runtime as the LOOM_PROVIDER variable (host or docker), which you can read in your scripts or use for conditional logic.

Host job example

version: v1
stages: [ci]

lint:
stage: ci
target: linux
script:
- golangci-lint run ./...

No image: key — Loom uses the host provider. The golangci-lint binary must be available on your machine.

Docker job example

version: v1
stages: [ci]

test:
stage: ci
target: linux
image: golang:1.22
script:
- go test ./...

The image: golang:1.22 key triggers the Docker provider. Loom pulls the image (if needed), creates a container, mounts your workspace, and runs the script inside it.

Running workflows with providers

Both host and Docker jobs are triggered the same way:

loom run --local --workflow .loom/workflow.yml

Loom inspects each job definition in the compiled graph and routes it to the correct provider automatically. You can verify which provider a job used by checking the provider events in the job's system section:

.loom/.runtime/logs/<run_id>/jobs/<job_id>/system/provider/events.jsonl

Docker workspace mount modes

When a job uses the Docker provider, Loom mounts the workspace into the container using one of two strategies:

ModeHow it worksWhen to use
bind_mountBind-mounts the host workspace directory directly into the containerUse when container writes should be visible in the snapshot
ephemeral_volume (default)Seeds a per-job volume from the snapshot, exports declared artifacts and cache paths, then removes the volume; other changes are discardedKeep container writes separate from the snapshot

Configuring the mount mode

MethodExamplePriority
CLI flagloom run --local --docker-workspace-mount bind_mountHighest
Environment variableLOOM_DOCKER_WORKSPACE_MOUNT=bind_mount loom run --local2
Repo configruntime.docker.workspaceMount in .loom/config.yml3
User configruntime.docker.workspaceMount in ~/.config/loom/config.yml4
Defaultephemeral_volumeLowest

The flag always wins. If you set both, the flag takes priority:

LOOM_DOCKER_WORKSPACE_MOUNT=ephemeral_volume loom run --local --docker-workspace-mount bind_mount
# → uses bind_mount (flag takes priority)

Isolation and security model

Host provider

  • Runs with local tools without container startup or image pulls.
  • Weakest isolation — the job inherits your full local environment, including credentials, shell configuration, and machine-specific paths.
  • Best for: quick local validation, jobs that need local toolchain access.

Docker provider

  • Stronger isolation — process and filesystem isolation via containers.
  • Your workspace is mounted into the container, so the job can read and write project files.
  • You are still trusting your local Docker daemon and the images you reference.
  • Best for: reproducible builds, testing against specific runtimes, isolating job environments from each other.
HostDocker
Startup workStarts a local shellImage lookup or pull, then container creation
EnvironmentFull local shell envOnly Loom variables + image defaults
Filesystem isolationNoneContainer filesystem with workspace mount
ReproducibilityDepends on local machineDepends on image, platform, and external inputs
When to chooseLocal iteration, native toolchainImage-defined toolchains, multi-runtime testing
caution

Host jobs inherit your local environment, which may include credentials or sensitive paths. When sharing logs or receipts for help, follow What to share and redact sensitive values.

Common pitfalls

Docker daemon not reachable

  • Symptom: Jobs with image: fail immediately with errors like "cannot connect to Docker daemon" or "pull access denied".
  • Fix: Verify Docker is running and accessible from your shell (docker info). Then retry. If the failure persists, check the provider events in the job's system section: .loom/.runtime/logs/<run_id>/jobs/<job_id>/system/provider/events.jsonl.

Job ran on host but you expected Docker

  • Symptom: The job seems to use host tooling; container-only tools aren't present.
  • Cause: image: is missing, empty, or removed by template resolution.
  • Fix: Ensure the job's resolved definition has a non-empty image: value. If you use templates or default, inspect the resolved workflow via loom compile to confirm the image is present.

Different behavior between host and Docker jobs

  • Symptom: A job works on host but fails in Docker (or the opposite).
  • Cause: Host jobs inherit your shell environment; Docker jobs only get Loom's workflow/job variables plus the image defaults.
  • Fix: Make all inputs explicit using workflow or job variables: (see Variables). Don't assume your shell environment is available inside a container.

Planned

  • Remote providers and runner pools (planned)