Runner Image
opencode-sandbox builds a Docker image for each sandbox. The image contains opencode, Node.js, and common CLI tools. Projects can extend the image with their own tooling.
Home directory
When rebuilding an image, all state in the VM’s home directory (/home/dev/) would get lost. Therefore, the home directory is copied to a volume and mounted to the running VM.
If the image changes between runs and the VM is rebuilt onto the new image, you will be presented with a prompt to keep, migrate, or reset your home volume (the prompt is skipped when the rebuild is deferred and the VM keeps running on the current image). In non-interactive mode the existing home volume is kept and you are told the image changed. The chosen action is applied automatically and the old volume is always kept. The state file is only updated once the action has actually executed. volume migrate, volume reset and volume edit remain available for manual management.
Base Image
The default runner image opencode-sandbox/runner-base is built from debian:trixie-slim and includes:
- opencode — symlinked to
/usr/local/bin/opencode - Node.js 26.x — for opencode LSP servers
- CLI tools —
git,ripgrep,jq,yq,curl,wget,xz-utils,file,gawk,less,lz4,moreutils,net-tools,parallel,recode,uuid
It creates and switches to the dev user and sets the workdir to /workspace — the mount point for the working directories.
opencode autoupdate and upgrades
opencode is pinned to a specific version at image build time and its runtime autoupdate is disabled via OPENCODE_DISABLE_AUTOUPDATE=true in the image, so the opencode binary in a sandbox is stable across runs. The pinned version is recorded as a Docker label (org.opencode-sandbox.opencode-version) on the image.
By default the latest release available at build time is used. Pin an explicit version on the build command with --opencode-version:
opencode-sandbox build --opencode-version 0.5.0
opencode-sandbox build # uses the latest release
How to upgrade: Rebuild the runner image with opencode-sandbox build. To pin a specific version, use --opencode-version.
On run/shell, when a newer opencode release exists than the version baked into the image, the launcher offers to rebuild the image (interactive) or prints a notice advising opencode-sandbox build (non-interactive). Images that predated the version label are force-rebuilt to pin a version.
The update check is rate-limited to keep it quiet:
- Once per day: the GitHub releases endpoint is queried at most once per 24 hours, machine-wide. The last successful check is recorded in the tool’s state directory (
~/.local/state/opencode-sandbox/updater.yaml). A failed or offline check does not start the window, so the next online session retries. - Once per version: each opencode version is offered for a rebuild at most once. Once the prompt for a version has been shown, that version is not offered again even on later days.
The opencode version baked into the image is also recorded in updater.yaml and reused on run/shell. This keeps the image identity (and therefore the cached microsandbox image) stable across runs: the version is only re-resolved from the network when an upgrade is actually performed (via the upgrade prompt or build), rather than on every invocation.
--opencode-versionis only available on thebuildcommand — it is not supported onrunorshell.
Docker-in-Docker Base Image
On top of the base image, opencode-sandbox provides an image with Docker-in-Docker (dind) enabled, opencode-sandbox/runner-base-dind.
Custom Runner
To add project-specific tools, create .opencode-sandbox/Dockerfile in your project, starting from one of the base images:
FROM opencode-sandbox/runner-base:latest
# or FROM opencode-sandbox/runner-base-dind:latest
# Install your project's toolchain into the dev user directory
RUN curl -fsSL https://pyenv.run | bash
Important: User context
The project image must end with USER dev active. If you need to run commands as root, switch back:
FROM opencode-sandbox/runner-base:latest
USER root
# Install your project's toolchain as root, e.g. via apt install
RUN apt-get update && apt-get install -y python3 && rm -rf /var/lib/apt/lists/*
USER dev
# everything else as dev
ENV configuration
ENV definitions in Dockerfiles are applied to running sandboxes. If you need to configure e.g. PATH, just set ENV PATH=...: in your Dockerfile.
Building and Managing Images
Build the image:
opencode-sandbox build # builds if image is missing or base changed
opencode-sandbox build -r # force rebuild
List cached images:
opencode-sandbox image list
The image name includes the project slug and Docker image hash, so changes to the Dockerfile automatically trigger a rebuild. When the resulting image digest differs from the image the existing project VM was booted from, the VM is recreated on the next run so it uses the new image (the home volume is preserved).
Image Lifecycle
Images can be pruned via the prune command or, more targeted, the image prune subcommand:
opencode-sandbox image prune --dry-run # see what's stale
opencode-sandbox image prune # actually remove them
See Commands for details on the prune command.
opencode-sandbox also auto-prunes all resources that are ephemeral, unused or haven’t been in use for more than 30 days by default. Cached runner images and home volumes are only pruned once they are older than the threshold, so a recently used project keeps its image and home state across restarts. See Sandboxes for more information and Configuration for how to configure auto-pruning.