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.
Docker
Section titled “Docker”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:
- Pulls the workspace’s
container.imageif it isn’t present, with the credentials from the runner user’s~/.docker/config.jsonfor private registries. - Creates a container named
gritz-<task-id>with the labelsgritz=true,gritz.task=<task-id>andgritz.runner=<runner-id>, and copies the matchinggritzbinary into it as/usr/local/bin/gritz(see Driver binaries). Its main process isgritz driver, listening on/gritz/driver.sock. - 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.
- 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.
Lambda MicroVMs
Section titled “Lambda MicroVMs”AWS_REGION=us-east-1 gritz runner --backend lambda-microvmThe 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:
- Launches a MicroVM from the workspace’s image (
run-microvm) on the first run, and waits until it is running. - Starts each run over the managed proxy, on port 8080, with a proxy auth token scoped to that port.
- Suspends the VM after every run (
suspend-microvm) and resumes it for the next (resume-microvm). - 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.
Workspace config
Section titled “Workspace config”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. |
Building the image
Section titled “Building the image”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.