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-dockeruse: 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:miseThe 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: commitA 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
dockerclient 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 asDOCKER_HOSTorPATHmeant for the container never reaches thedockerclient. - 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.