kosa8 / Integrations

Integration · dockerode

dockerode on kosa8

dockerode is the Docker client most Node.js tools are built on. It reads DOCKER_HOST, so pointing it at kosa8 needs no code change.

01What was tested

Tested with kosa8 v0.9.10, on 15 October 2026 on an Apple silicon Mac (macOS, arm64), with the released v0.9.10 binaries and guest image, with dockerode 5.0.1 on Node.js 25.9.0.

  • Worked: pull with followProgress, createContainer, start, exec with demuxStream and exec.inspect() for the exit code, logs, and remove({ force: true }).

02Set it up

03A tested snippet

dockerode-test.mjs
// dockerode: pull, create + start a container, exec in it, read its logs, remove it.
import Docker from "dockerode";
 
const docker = new Docker(); // reads DOCKER_HOST
await new Promise((resolve, reject) =>
  docker.pull("alpine:3.20", (err, stream) =>
    err ? reject(err) : docker.modem.followProgress(stream, (e) => (e ? reject(e) : resolve()))));
 
const container = await docker.createContainer({
  Image: "alpine:3.20",
  Cmd: ["sh", "-c", "echo hello-from-kosa8; sleep 30"],
  HostConfig: { AutoRemove: false },
});
try {
  await container.start();
 
  const exec = await container.exec({ Cmd: ["uname", "-m"], AttachStdout: true, AttachStderr: true });
  const stream = await exec.start({});
  let out = "";
  docker.modem.demuxStream(stream, { write: (b) => (out += b) }, process.stderr);
  await new Promise((r) => stream.on("end", r));
  const { ExitCode } = await exec.inspect();
 
  const logs = (await container.logs({ stdout: true })).toString();
  console.log(`exec: uname -m -> ${out.trim()} (exit ${ExitCode})`);
  console.log(`logs: ${logs.includes("hello-from-kosa8") ? "hello-from-kosa8" : JSON.stringify(logs)}`);
  if (ExitCode !== 0 || !out.trim() || !logs.includes("hello-from-kosa8")) process.exitCode = 1;
} finally {
  await container.remove({ force: true });
}
output
node dockerode-test.mjs
exec: uname -m -> aarch64 (exit 0)
logs: hello-from-kosa8

04Limits

  • No image removal through the API yet. docker.getImage(name).remove() calls DELETE /images/{name}, which v0.9.10 does not serve (404). Remove images with kosa8 rmi.
  • Bind mounts only from allowed folders. HostConfig.Binds works only below a folder named with kosa8 daemon start --allow-mount DIR. The Docker socket itself is never shared.