BlaiseBlaise
Documentation
Runner and PlugsHow-to guides

Run the agent in Docker

Run the agent and the plugs after it in a container that pauses and resumes with the session.

blaise:docker runs everything after it in a container named after the session. It lives in its own package, @blaiseagent/plugs-docker.

1. Add the package

bun add @blaiseagent/plugs-docker

use: blaise:docker finds the package by itself, because blaise:<name> falls back to @blaiseagent/plugs-<name>.

2. Add the plug

setup:
  - use: blaise:docker
    with:
      image: node:22-slim
      volume: /srv/checkouts/app
      workdir: /workspace
  - use: blaise:mise

The image needs sh, setsid (to stop the agent and its subprocesses), and the common POSIX tools for the file system: uname, stat, ls, mkdir, rmdir, rm, mv, cp, cat, test, ln, readlink and realpath. Busybox-based images such as Alpine have them all. volume is a directory on the runner, mounted at workdir.

3. Choose what a pause does

By default a pause stops the container. Its file system, including the agent's own session history, is still there when the next message starts it again.

To keep no container between messages, commit it instead:

- use: blaise:docker
  with:
    image: node:22-slim
    pause: commit

A pause then saves the container as an image named blaise-snapshot:<session> and removes the container. The next run starts a new container from that image. The commit happens only when the session may resume; otherwise the container is just stopped. If the commit fails, the plug stops the container and logs a warning.

4. Let several runners resume

Containers are found by name, so any instance that talks to the same Docker daemon can resume the session. Instances that share one runner token are treated as one runner, and a resume goes to it; point them at a shared daemon with DOCKER_HOST. With one instance you need nothing.

Things to know

  • Secrets are not on command lines. The environment of a command goes to the docker client as --env BLAISE_ENV_<n>, a neutral name, and the value travels in the client's own environment. Inside the container the supervisor gives each value its real name and removes the neutral one. Because the names are written into a script, each must be a valid shell identifier. A variable such as DOCKER_HOST or PATH meant for the container never reaches the docker client.
  • The container runs with --init, so processes the agent leaves behind are reaped.
  • A daemon that cannot be reached is an error, not a missing container: the plug asks the daemon whether the container and the snapshot exist, and fails the run if it cannot get an answer.
  • Killing a command stops the client, not the process in the container. Pausing the session stops the container, which ends everything in it.
  • Teardown removes the container and the snapshot.

For all inputs, see Shipped plugs.

On this page