Allow Sandbox container limits overrides

This commit is contained in:
Jarek Rozanski 2026-09-28 12:01:20 +02:00
commit 854ccf87be
No known key found for this signature in database
2 changed files with 11 additions and 4 deletions

View file

@ -35,12 +35,19 @@ STATE_DIR := $(HOME)/.local/state/opencode
# it fails fast rather than thrashing. Sized to leave ~1 GiB / 2 CPUs of # it fails fast rather than thrashing. Sized to leave ~1 GiB / 2 CPUs of
# headroom below the VM's own allocation for the VM/podman/gvproxy itself -- # headroom below the VM's own allocation for the VM/podman/gvproxy itself --
# adjust alongside `podman machine set` if you resize the machine again. # adjust alongside `podman machine set` if you resize the machine again.
# Override any of these per-invocation by exporting OPENCODE_SANDBOX_MEMORY,
# OPENCODE_SANDBOX_MEMORY_SWAP, and/or OPENCODE_SANDBOX_CPUS before running
# `make opencode`/`make shell`.
OPENCODE_SANDBOX_MEMORY ?= 3072m
OPENCODE_SANDBOX_MEMORY_SWAP ?= 3072m
OPENCODE_SANDBOX_CPUS ?= 4
RUN_FLAGS := \ RUN_FLAGS := \
--rm -it \ --rm -it \
--userns=keep-id \ --userns=keep-id \
--memory=3072m \ --memory=$(OPENCODE_SANDBOX_MEMORY) \
--memory-swap=3072m \ --memory-swap=$(OPENCODE_SANDBOX_MEMORY_SWAP) \
--cpus=4 \ --cpus=$(OPENCODE_SANDBOX_CPUS) \
--network $(NETWORK_NAME) \ --network $(NETWORK_NAME) \
--network-alias $(WORKDIR_NAME) \ --network-alias $(WORKDIR_NAME) \
-v $(CURDIR):/workspace \ -v $(CURDIR):/workspace \

View file

@ -86,7 +86,7 @@ Bumping a pinned LSP version means editing the corresponding `ARG`/`FROM` tag in
Because these are real host paths shared by every container regardless of workdir, logging into OpenCode once carries over to every project you use the sandbox in. Because these are real host paths shared by every container regardless of workdir, logging into OpenCode once carries over to every project you use the sandbox in.
- Both run targets join a shared, auto-created Podman network (`opencode-sandbox-net`) under a `--network-alias` derived from the current directory's name, so a container started from another dev-container setup on the same network can reach this one by that name (and vice versa). - Both run targets join a shared, auto-created Podman network (`opencode-sandbox-net`) under a `--network-alias` derived from the current directory's name, so a container started from another dev-container setup on the same network can reach this one by that name (and vice versa).
- Both run targets also cap the container to `--memory=3072m --memory-swap=3072m --cpus=4`. Without this, a heavy JVM build tool (Gradle's daemon plus its separate Kotlin-compiler daemon are the worst offenders — both auto-size their heap off "available" memory with no idea they're sharing a fixed-size VM) can consume the entire `podman machine`'s RAM. That starves the VM's own guest kernel, which stalls the processes Podman itself needs to stay responsive — so the *whole machine* hangs, not just the container. The cap forces a contained OOM kill instead. Sized to leave headroom below the VM's own allocation for the VM/podman/gvproxy itself — adjust both together if you resize the machine (`podman machine set --memory <MB> --cpus <N> podman-machine-default`, machine must be stopped first). The `Containerfile` also sets a default `GRADLE_OPTS=-Xmx1024m` so the Gradle daemon itself doesn't try to claim the whole container ceiling; a project whose Kotlin-compiler daemon also needs bounding should set `kotlin.daemon.jvmargs` in its own `gradle.properties`. - Both run targets also cap the container to `--memory=3072m --memory-swap=3072m --cpus=4`. Without this, a heavy JVM build tool (Gradle's daemon plus its separate Kotlin-compiler daemon are the worst offenders — both auto-size their heap off "available" memory with no idea they're sharing a fixed-size VM) can consume the entire `podman machine`'s RAM. That starves the VM's own guest kernel, which stalls the processes Podman itself needs to stay responsive — so the *whole machine* hangs, not just the container. The cap forces a contained OOM kill instead. Sized to leave headroom below the VM's own allocation for the VM/podman/gvproxy itself — adjust both together if you resize the machine (`podman machine set --memory <MB> --cpus <N> podman-machine-default`, machine must be stopped first). The `Containerfile` also sets a default `GRADLE_OPTS=-Xmx1024m` so the Gradle daemon itself doesn't try to claim the whole container ceiling; a project whose Kotlin-compiler daemon also needs bounding should set `kotlin.daemon.jvmargs` in its own `gradle.properties`. These defaults can be overridden per-invocation by exporting `OPENCODE_SANDBOX_MEMORY`, `OPENCODE_SANDBOX_MEMORY_SWAP`, and/or `OPENCODE_SANDBOX_CPUS` before running `make opencode`/`make shell` (e.g. `OPENCODE_SANDBOX_MEMORY=4096m OPENCODE_SANDBOX_CPUS=6 make shell`).
## macOS-specific notes ## macOS-specific notes