Increase Podman resources
This commit is contained in:
parent
3cd15d53a2
commit
ceac06e94a
3 changed files with 33 additions and 1 deletions
|
|
@ -164,6 +164,17 @@ ENV PATH="${JAVA_HOME}/bin:${PNPM_HOME}/bin:${GOROOT}/bin:${GOPATH}/bin:${CARGO_
|
||||||
# NODE_PATH is the fallback once that climb reaches the filesystem root.
|
# NODE_PATH is the fallback once that climb reaches the filesystem root.
|
||||||
ENV NODE_PATH=/usr/local/lib/node_modules
|
ENV NODE_PATH=/usr/local/lib/node_modules
|
||||||
|
|
||||||
|
# GRADLE_OPTS: bounds the Gradle daemon's own heap. Gradle's default heap
|
||||||
|
# auto-sizing goes off whatever memory it sees as "available" -- with no
|
||||||
|
# cap it sizes against the Makefile's --memory container ceiling in full,
|
||||||
|
# leaving nothing for the separate Kotlin-compiler daemon Gradle forks
|
||||||
|
# alongside it (see the RUN_FLAGS comment in the Makefile for the full
|
||||||
|
# story: an uncapped build here doesn't just OOM the container, it can
|
||||||
|
# starve the whole podman-machine VM). This only bounds the Gradle daemon
|
||||||
|
# itself -- a project needing the Kotlin daemon capped too should set
|
||||||
|
# `kotlin.daemon.jvmargs` in its own gradle.properties.
|
||||||
|
ENV GRADLE_OPTS="-Xmx1024m -XX:MaxMetaspaceSize=256m"
|
||||||
|
|
||||||
# Fixed HOME: the container is run with --userns=keep-id, so the runtime UID
|
# Fixed HOME: the container is run with --userns=keep-id, so the runtime UID
|
||||||
# is whatever host user invoked `podman run`, which has no /etc/passwd entry
|
# is whatever host user invoked `podman run`, which has no /etc/passwd entry
|
||||||
# inside the image. A plain ENV HOME is unaffected by that UID mapping, so we
|
# inside the image. A plain ENV HOME is unaffected by that UID mapping, so we
|
||||||
|
|
|
||||||
20
Makefile
20
Makefile
|
|
@ -18,9 +18,29 @@ STATE_DIR := $(HOME)/.local/state/opencode
|
||||||
# inotify file-change events don't propagate into the container. Not a
|
# inotify file-change events don't propagate into the container. Not a
|
||||||
# blocker for this sandbox, just a rough edge if a tool relies on watching
|
# blocker for this sandbox, just a rough edge if a tool relies on watching
|
||||||
# /workspace for live changes.
|
# /workspace for live changes.
|
||||||
|
#
|
||||||
|
# --memory/--memory-swap/--cpus: on macOS, `podman machine`'s Linux VM has a
|
||||||
|
# FIXED resource allocation (check with `podman machine inspect`; currently
|
||||||
|
# 4 GiB / 6 CPUs, bumped up from the 2 GiB default -- see `podman machine
|
||||||
|
# set --memory <MB> podman-machine-default`, which requires the machine to
|
||||||
|
# be stopped first). Without a cgroup cap here, a memory-hungry build tool
|
||||||
|
# (Gradle's daemon and its separate Kotlin-compiler daemon are the worst
|
||||||
|
# offenders -- both size their heap off "available" memory with no idea
|
||||||
|
# they're sharing a small VM) can consume the VM's *entire* RAM. That
|
||||||
|
# doesn't just OOM-kill the container -- it starves the VM's own guest
|
||||||
|
# kernel, which stalls the very processes Podman needs to stay responsive
|
||||||
|
# (its API socket, gvproxy, SSH), making the whole machine appear to hang.
|
||||||
|
# Capping the container forces a contained OOM kill instead. --memory-swap
|
||||||
|
# equal to --memory disables extra swap for the container specifically, so
|
||||||
|
# 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 --
|
||||||
|
# adjust alongside `podman machine set` if you resize the machine again.
|
||||||
RUN_FLAGS := \
|
RUN_FLAGS := \
|
||||||
--rm -it \
|
--rm -it \
|
||||||
--userns=keep-id \
|
--userns=keep-id \
|
||||||
|
--memory=3072m \
|
||||||
|
--memory-swap=3072m \
|
||||||
|
--cpus=4 \
|
||||||
--network $(NETWORK_NAME) \
|
--network $(NETWORK_NAME) \
|
||||||
--network-alias $(WORKDIR_NAME) \
|
--network-alias $(WORKDIR_NAME) \
|
||||||
-v $(CURDIR):/workspace \
|
-v $(CURDIR):/workspace \
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,11 @@ 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`.
|
||||||
|
|
||||||
## macOS-specific notes
|
## macOS-specific notes
|
||||||
|
|
||||||
- Podman on macOS runs everything inside a Linux VM (`podman machine`, backend `libkrun`/`applehv`, virtiofs file sharing). The Makefile detects this and starts a stopped machine automatically before `build`, `opencode`, or `shell`.
|
- Podman on macOS runs everything inside a Linux VM (`podman machine`, backend `libkrun`/`applehv`, virtiofs file sharing). The Makefile detects this and starts a stopped machine automatically before `build`, `opencode`, or `shell`. This machine has a fixed CPU/memory allocation (`podman machine inspect`) — bump it (see above) if JVM-heavy builds are still tight even with the container's own cap.
|
||||||
- SELinux volume-relabeling suffixes (`:Z`/`:z`) are intentionally omitted — macOS's host filesystem has no SELinux concept, so they'd be a no-op.
|
- SELinux volume-relabeling suffixes (`:Z`/`:z`) are intentionally omitted — macOS's host filesystem has no SELinux concept, so they'd be a no-op.
|
||||||
- Known virtiofs limitation: inotify/file-watch events from the host don't propagate into the container. Not a blocker for normal use, just worth knowing if a tool inside the container tries to watch `/workspace` for live host-side changes.
|
- Known virtiofs limitation: inotify/file-watch events from the host don't propagate into the container. Not a blocker for normal use, just worth knowing if a tool inside the container tries to watch `/workspace` for live host-side changes.
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue