Skip to main content
One constraint shapes every decision here: your container must reach the host’s virtualization device (/dev/kvm on Linux). Granting it is a privileged operation with a real security cost, and every decision below is about paying that cost deliberately.

Prerequisites

  • A working BoxLite install (Python boxlite or Node @boxlite-ai/boxlite) and a machine with hardware virtualization — see Installation.
BoxLite needs hardware virtualization to start each sandbox microVM. A container has no access to /dev/kvm by default, so a box created inside an unprivileged container fails to start and raises a standard RuntimeError (Python) / Error (Node). The configuration below is what grants that access.

Why privileged access is required

Each BoxLite sandbox is a microVM, not a shared-kernel container. Starting a microVM requires the kernel virtualization interface, which on Linux is the character device /dev/kvm. Two conditions must hold inside the container:
  1. The /dev/kvm device node must be present in the container.
  2. The process must have permission to open it.
Granting both typically means running the container with elevated privileges (--privileged in Docker, securityContext.privileged: true in Kubernetes) and passing the device through from the host. This is the same trust boundary you accept whenever you run nested virtualization in a container. Security consequence: a privileged container can largely bypass container isolation from the host. The isolation BoxLite gives you is inside the boxes (each box is a microVM that untrusted agent code cannot escape), not between the agent service container and its host. Treat the host that runs the agent service as part of your trusted compute base, and do not co-tenant it with workloads you do not trust.

Quick Example: minimal agent service

A minimal agent service is your code plus the SDK. The example below is a small handler that runs untrusted code in a CodeBox and returns the result; it is what you would containerize.
The rest of this page is about giving the container running app.py access to /dev/kvm.

Docker deployment

Run the agent service inside a Docker container. The container must run with --privileged and have /dev/kvm passed through.

Dockerfile

Run with KVM access

Multi-tenancy warning

Running BoxLite inside a privileged Docker container is appropriate for single-tenant deployments where you control everything on the host. It is not recommended for multi-tenant environments: a privileged container weakens the boundary between the container and its host, so a compromise of the agent service container can affect the host and any neighbors on it. For multi-tenant isolation, run each tenant’s agent service on its own dedicated VM rather than relying on the container boundary.

Kubernetes deployment

On Kubernetes, the same two requirements apply: the pod must be privileged, and /dev/kvm must be mounted from the host. Because only nodes that actually expose /dev/kvm can start boxes, schedule the pod onto KVM-enabled nodes with a node selector.

Pod manifest

Notes

  • Privileged pods are a cluster-wide security consideration. If your cluster enforces Pod Security admission, a privileged pod requires the privileged policy level for its namespace.
  • Only nodes with KVM available can run these pods. Label and select those nodes explicitly; do not rely on default scheduling.
  • The container’s resources.limits bound the agent service process, not the individual boxes. Set per-box limits with cpus / memory_mib on BoxOptions (see Compute Resources), and ensure the pod limit is large enough for the sum of concurrent boxes plus overhead.

Pre-deployment checklist

Before shipping a BoxLite-backed agent service:
  • Per-box resource limits set. Configure cpus / memory_mib (and disk_size_gb if you need persistence) on every box so a runaway agent cannot exhaust the host. See Running sandboxes at scale.
  • Error handling covers low-level failures. Catch standard RuntimeError (Python) / bare Error (Node) in addition to BoxliteError; image pull failures and missing virtualization do not subclass BoxliteError. See Error Handling.
  • Cleanup is guaranteed. Use async with for one-shot boxes, or runtime.remove(id, force=True) for runtime-managed boxes, so sessions are reclaimed.
  • Concurrency is sized to the host. Estimate total resource use as per-box limits times expected concurrency, and keep it under the pod/host limits.
  • Host trust is appropriate. The privileged container does not isolate the agent service from its host; keep untrusted neighbors off the host.

Troubleshooting

Box fails to start inside the container with RuntimeError

The most common cause is that /dev/kvm is not accessible inside the container. Verify:
For Docker, confirm both --privileged and --device /dev/kvm:/dev/kvm are set. For Kubernetes, confirm securityContext.privileged: true, the hostPath mount with type: CharDevice, and that the pod landed on a KVM-enabled node.

Pod is rejected by Pod Security admission

A privileged pod requires the privileged Pod Security level for its namespace. Either run it in a namespace labeled for the privileged policy, or move the agent service to a dedicated cluster/node pool that permits privileged pods.

Boxes start but the pod is OOM-killed under load

The pod’s resources.limits.memory bounds the whole pod, including every box’s microVM memory. Either lower per-box memory_mib and concurrency, or raise the pod memory limit to cover the sum of concurrent boxes plus overhead. See Compute Resources.

Node has no /dev/kvm

Not every node supports nested virtualization (this is common on cloud instance types without nested-virt enabled). Label only the nodes that expose /dev/kvm and use a nodeSelector so the pod is never scheduled onto a node that cannot start boxes.

See Also