Skip to content

Backends

A runner starts every task’s sandbox through one backend, chosen with --backend. The backend creates the sandbox, starts and suspends it around each run, connects the runner to the driver inside it, and destroys it when the task is archived.

Docker Lambda MicroVMs
--backend docker (the default) lambda-microvm
Sandbox A container on the runner’s Docker daemon An AWS Lambda MicroVM
Workspace section container: lambda_microvm:
Image Any Linux image; the runner copies the driver in A MicroVM image with the driver as its entrypoint, ARM64 only
Between runs The container is stopped The VM is suspended
Runner reaches the driver docker exec tunnel to /gritz/driver.sock AWS’s managed proxy
Capacity The runner host’s AWS’s, up to your account limits

Use Docker to get started, on a workstation or a dedicated host, or when tasks need Docker-specific setup: volumes, networks, other runtimes such as sysbox, or privileged containers.

Use Lambda MicroVMs to run many tasks without sizing a host for them, with each task isolated in its own VM and nothing left running between runs.

A workspace can have both a container: and a lambda_microvm: section, so one workspaces.yaml can serve runners on either backend. Each backend checks only its own section, when a task’s run starts, so a missing section fails that run rather than the runner’s start.

The runner talks to the Docker daemon from its environment (DOCKER_HOST, or the local socket), so it needs access to it: run it as a user in the docker group, or mount /var/run/docker.sock into the runner’s container.

For each task the runner:

  1. Pulls the workspace’s container.image if it isn’t present, with the credentials from the runner user’s ~/.docker/config.json for private registries.
  2. Creates a container named gritz-<task-id> with the labels gritz=true, gritz.task=<task-id> and gritz.runner=<runner-id>, and copies the matching gritz binary into it as /usr/local/bin/gritz (see Driver binaries). Its main process is gritz driver, listening on /gritz/driver.sock.
  3. Starts the container for each run and stops it afterwards. The container’s filesystem survives between runs, so a woken task finds its checkout where it left it.
  4. Removes the container when the task is archived.

The container: section maps onto the container’s settings: image, user, working_dir, environment, volumes, networks, network_mode, group_add, runtime and privileged. See workspaces.yaml.

The driver inside the container connects to the server at the runner’s --server URL. When that is localhost, as in local development, the container can’t reach it on the default bridge network: use network_mode: host on Linux, or a URL such as http://host.docker.internal:6464.

Terminal window
AWS_REGION=us-east-1 gritz runner --backend lambda-microvm

The runner resolves AWS credentials and the region through the standard AWS SDK chain; --lambda-microvm-region overrides the region. The runner’s credentials make the MicroVM control-plane calls: RunMicrovm, GetMicrovm, SuspendMicrovm, ResumeMicrovm, TerminateMicrovm and CreateMicrovmAuthToken. Sandboxes never hold them.

For each task the runner:

  1. Launches a MicroVM from the workspace’s image (run-microvm) on the first run, and waits until it is running.
  2. Starts each run over the managed proxy, on port 8080, with a proxy auth token scoped to that port.
  3. Suspends the VM after every run (suspend-microvm) and resumes it for the next (resume-microvm).
  4. Terminates the VM when the task is archived (terminate-microvm).

A VM runs for at most max_duration_seconds, 8 hours by default and at most, so keep tasks that wake up over days on Docker.

workspaces:
example:
secrets:
CLAUDE_CODE_OAUTH_TOKEN: ${env:CLAUDE_CODE_OAUTH_TOKEN}
lambda_microvm:
image_identifier: arn:aws:lambda:us-east-1:123456789012:microvm-image/gritz-driver
execution_role: arn:aws:iam::123456789012:role/gritz-microvm
egress_connector: arn:aws:lambda:us-east-1:aws:network-connector:aws-network-connector:INTERNET_EGRESS
agent:
type: claude
cwd: /root
Field Required
image_identifier yes The MicroVM image’s ARN.
execution_role yes The IAM role the VM runs as. It needs whatever the agent’s work needs, and no MicroVM permissions.
egress_connector yes The network connector for outbound traffic, so the driver can reach the server: INTERNET_EGRESS or a VPC connector.
ingress_connector no The network connector the runner’s proxy traffic comes in through. Defaults to the managed ALL_INGRESS; a connector scoped to port 8080 is tighter.
region no Must match the runner’s region if set. One runner serves one region.
max_duration_seconds no The VM’s maximum lifetime, up to 28800 (8 hours), the default.
environment no Environment variables for every run. A VM has no environment of its own, so these are passed with each run.

A MicroVM image is built by Lambda from a zip holding a Dockerfile and a linux/arm64 gritz binary, with gritz driver --aws-lambda-hooks as its entrypoint. Install the agent CLIs and tools your workspaces need in the same Dockerfile. The backend’s README has the full recipe: the example microvm.Dockerfile, the create-microvm-image call with its hooks, the build role, and warming the image with --aws-lambda-validate so cold VMs start their tools quickly.

Unlike Docker, the driver is part of the image, so rebuild the image with the new binary whenever you upgrade the runner.