What you can set
The fields below are forwarded through**kwargs to the underlying BoxOptions in wrapper classes such as SimpleBox/CodeBox, and can also be used directly with BoxOptions(...).
SimpleBox’s convenience parameters only coverimage / rootfs_path / memory_mib / cpus / runtime / name / auto_remove / reuse_existing;env / entrypoint / cmd / user / working_dirand so on are forwarded through**kwargstoBoxOptions, so their names and types followBoxOptions(for example Python’sworking_dir, and the construction-timeenvbeing a list of tuples).
Quick Example
The shortest path: useSimpleBox to inject environment variables, run as a non-root user, set the working directory, and then run a command to verify.
The relationship between entrypoint and cmd
An OCI image has two directives: ENTRYPOINT (the executable) and CMD (default arguments). The final startup command is the concatenation of the two: ENTRYPOINT + CMD.
- Set only
cmd: replace the default arguments, keep the image’s ENTRYPOINT. - Set only
entrypoint: replace the executable. - Set both: fully customize the startup behavior.
python:alpine) put the default command in CMD rather than ENTRYPOINT. To pass arguments like -c, you must explicitly set entrypoint=["python3"], otherwise the arguments have nothing to attach to.
Important:entrypoint + cmdcontrols the container init process. If that init command is short-lived (it exits as soon as it finishes, e.g.python3 -c "print(...)"), the container enters the Stopped state after init exits, and you can no longer callbox.exec(...); it raisesRuntimeError: internal error: spawn_failed: Container init process exited — cannot exec. ... incompatible container status: \Stopped“. Therefore: if you want to customize init viaentrypoint + cmdand also keepexec-ing afterward, init must be a long-lived process (such as sleep or a service process). The example below changes init totime.sleep(120), after whichexecreliably returnsexit=0. If you only run one command and never exec again, a short-lived init is also fine.
user: running as non-root
user accepts a username or a UID, in the format <name|uid>[:<group|gid>]. Non-numeric usernames are resolved from the container’s /etc/passwd / /etc/group.
exec (env here is a dict):
Return value: ExecResult
box.exec(...) returns an ExecResult (a dataclass in the Python wrapper layer).
Node’s
ExecResult fields are exitCode / stdout / stderr.
Troubleshooting
Passing a string as the volume’s third element causes a TypeError
A volume’s third element is the booleanread_only; the strings "ro"/"rw" are CLI-only and raise TypeError here. See Volumes.
Construction-time env passed as a dict reports a type error (Python)
SimpleBox(env=...) / BoxOptions(env=...) requires list[tuple[str, str]] at construction time:
box.exec(env=...) uses a dict at execution time. The distinction: a list at construction time, a dict at exec time.
cmd arguments take no effect / the image has no ENTRYPOINT
If the image’s default command is in CMD (not ENTRYPOINT), setting cmd=["-c", ...] alone leaves the arguments with no executable to attach to. Explicitly set entrypoint=["python3"] (or the target executable); see the entrypoint example above.
After setting entrypoint + cmd to a short-lived command, exec reports incompatible container status: Stopped
entrypoint + cmd is the container init process. A short-lived init (which exits as soon as it finishes) puts the container into the Stopped state, and a subsequent exec raises:
exec-ing, make init long-lived (sleep / a service); if you only run one command, use a short-lived init and do not exec again. See the entrypoint example above.
working_dir pointing to a nonexistent directory makes exec raise RuntimeError
working_dir (or exec(cwd=...)) must be a directory that already exists in the image. When it points to a nonexistent directory (e.g. setting working_dir="/work" on alpine), the box still creates successfully, but the first exec raises:
alpine has /tmp, /root), or create one first via exec from an existing working directory:
exec exits non-zero without raising
This is expected behavior: when exec fails (the command returns non-zero) it does not raise but returns an ExecResult with exit_code != 0. Always check result.exit_code (Node: result.exitCode).
A missing command / image pull failure raises a standard exception
- Missing command: raises a standard
RuntimeError(Python) / a bareError(Node), not aBoxliteErrorsubclass. - Image pull network flakiness: raises a
RuntimeError, which you can retry aftertry/except.
except Exception rather than only catching BoxliteError.
No hardware virtualization causes startup failure
BoxLite requires hardware virtualization (an environment constraint):- Linux: requires KVM (
/dev/kvmavailable); under WSL2 the user must be in thekvmgroup. - macOS: uses Apple Hypervisor.framework, no
/dev/kvmrequired (macOS arm64 supported). - No virtualization: startup fails on
async withentry. The process does not crash and can be caught withtry/exceptto report the issue.

