Mount in a container
Run Tonbo Artifacts in Docker, Podman, or any OCI runtime, bind-mount from the host or run FUSE inside the container.
Two patterns. Pick by your runtime:
- From a host mount (recommended for Docker / Podman / containerd / nerdctl): mount the workspace once on the host, bind it into every container with
-v. Containers stay fully unprivileged. - FUSE inside the container (microVMs / gVisor / Kata): the container runs the CLI itself and mounts inside the guest. Requires
SYS_ADMINinside the container.
If your runtime shares the host kernel, use the first pattern. Only use the second if you're running a sandbox runtime that doesn't.
From a host mount (recommended)
Mount the workspace on the host once. Bind it into as many containers as you want via -v. The containers don't need SYS_ADMIN, /dev/fuse, or any FUSE awareness, they just see a regular directory.
Host setup:
curl -fsSL https://artifacts.tonbo.dev/install.sh | bash
artifacts login
mkdir -p /mnt/work
artifacts mount your-org/my-workspace /mnt/work
Run containers against the bind:
docker run --rm -it -v /mnt/work:/data your-image
For Podman, swap docker run for podman run.
docker-compose
services:
agent:
image: your-image
volumes:
- /mnt/work:/data
Why this is the recommended path
- Containers stay completely unprivileged, pass any hardened image-scan or admission policy.
- One host mount serves N containers simultaneously; no per-container FUSE setup.
- Update the CLI on the host once; container images don't carry it.
- The container image doesn't need to know Tonbo Artifacts exists.
FUSE inside the container (microVMs, gVisor, Kata)
Use this only when the runtime doesn't share the host kernel, the FUSE-on-host pattern above can't reach into the guest. The CLI runs inside the guest and mounts there.
SYS_ADMIN (or --privileged) inside the container is required for the kernel mount() syscall. It applies inside the container's namespace, not on the host like --privileged would, but treat it as an elevated capability: avoid combining with other broad permissions, and don't grant it to untrusted images.
Dockerfile
FROM ubuntu:24.04
RUN apt-get update -qq && \
apt-get install -y -qq curl ca-certificates fuse3 && \
rm -rf /var/lib/apt/lists/*
RUN curl -fsSL https://artifacts.tonbo.dev/install.sh | bash
RUN artifacts --version
Platform worker mount ticket
For Daytona-style platform workers, your backend issues a signed mount ticket. Inject the config into the worker as a secret-backed file, then run the mount config entrypoint inside the guest:
mkdir -p /run/tonbo/artifacts
chmod 0700 /run/tonbo/artifacts
cp mount-ticket.json /run/tonbo/artifacts/mount-ticket.json
chmod 0600 /run/tonbo/artifacts/mount-ticket.json
artifacts mount --ticket-file /run/tonbo/artifacts/mount-ticket.json /mnt/work
Run
docker run --rm -it \
--cap-add SYS_ADMIN \
--device /dev/fuse \
--security-opt apparmor=unconfined \
-v "$PWD/mount-ticket.json:/run/tonbo/artifacts/mount-ticket.json:ro" \
your-image bash
Inside the container:
artifacts mount --ticket-file /run/tonbo/artifacts/mount-ticket.json /mnt/work
docker-compose
services:
agent:
image: your-image
cap_add:
- SYS_ADMIN
devices:
- /dev/fuse
security_opt:
- apparmor=unconfined
volumes:
- ./mount-ticket.json:/run/tonbo/artifacts/mount-ticket.json:ro
command: >
bash -c "artifacts mount --ticket-file /run/tonbo/artifacts/mount-ticket.json /mnt/work && exec your-agent"
Cleanup
Short-lived containers don't need explicit unmount, the kernel tears the mount down when the container exits.
For long-running containers rotating tokens:
artifacts unmount /mnt/work
cp new-mount-ticket.json /run/tonbo/artifacts/mount-ticket.json
chmod 0600 /run/tonbo/artifacts/mount-ticket.json
artifacts mount --ticket-file /run/tonbo/artifacts/mount-ticket.json /mnt/work
Troubleshooting
The host mount didn't come up before docker run. Verify ls /mnt/work on the host shows your workspace contents first.
The container doesn't have SYS_ADMIN. Re-check --cap-add SYS_ADMIN (Docker / Podman) or cap_add (Compose).
The host kernel doesn't have FUSE loaded, or --device /dev/fuse is missing. Confirm ls -la /dev/fuse on the host before launching the container.
On hardened hosts the mount() syscall can be denied even with SYS_ADMIN. --security-opt apparmor=unconfined (Docker) or labeling the container unconfined_t (Podman / SELinux) lets the mount proceed.