A client for the Docker Engine API (and Podman's compatible one) for
Jennifer programs: create, start, stop, kill,
wait for and remove containers, read their logs and a stats sample; pull,
tag, build and remove images; networks, volumes, detached exec, ping,
version, info and prune; call for any other endpoint. It negotiates the
API version with the daemon, checks names and references before sending,
and puts a deadline and a cap on every answer.
Infrastructure as Code (IaC). Containers, images, networks and volumes
can be provisioned from a Jennifer program kept in version control and
reviewed like any other code. Not every create verb is idempotent:
createContainer and createNetwork fail (409) when the name is taken,
while createVolume returns an existing volume of the same driver unchanged,
and pull, tagImage and build can be run again. A re-runnable script
lists what exists first (containers, networks, volumes, images, with
label filters) or inspects by name; startContainer reports a container
that already runs. There is no plan or diff step, no Compose file support,
and the deck does not detect drift.
jvc add @deckyard/dockerThis vendors the deck to vendor/<scope>/docker/. Without jvc, unpack the
src/ subtree of a release archive (<scope>-docker-<version>.tar.gz) there.
import "@deckyard/docker/" as docker;
def c as docker.Client init docker.negotiate(docker.client("tcp://127.0.0.1:2375"));
def spec as docker.ContainerSpec init docker.withCmd(docker.containerSpec("alpine:3.22"), ["uname", "-a"]);
def id as string init docker.createContainer($c, "", $spec);
docker.startContainer($c, $id);
docker.waitContainer($c, $id, "not-running");
io.printf("%s", docker.logs($c, $id, []).stdout);
docker.removeContainer($c, $id, false, false);
The daemon is reached at tcp://host:port (its plain port: root-equivalent,
so only on this machine unless withPlainHttp) or https:// through a
socket proxy (withToken, withBasicAuth). unix:// is refused until the
http module can reach a Unix socket; until then expose the socket on
loopback, as Connecting shows. Logs, pull and build
output are read whole once they end; following a log and events wait for
streaming responses.
Jennifer 0.26.0 or newer, with the net capability (the default binary;
not jennifer-tiny). A Docker daemon speaking Engine API 1.41 or later
(Docker 20.10 and newer; Podman 6.2's service reports 1.44), reachable over
TCP or an https proxy.
tools/check-all.sh # the full gate, as CI runs it
jennifer test src/docker_test.j # the test overlay
tools/check-docs.sh # docs against the code
tools/pack.sh dist # build the release archiveThe suite runs against a loopback fake with Docker's recorded replies; CI only parse-checks the examples, which need a daemon.
LGPL-3.0-only, see LICENSE. Copyright (C) 2026 mplx <mplx@jennifer-lang.dev>.
tools/check-headers.sh checks every source file's SPDX header against
deck.toml.