# opencode-devbox — variant image # # FROMs a base- image produced by Dockerfile.base and adds only # the variant-specific tools (opencode, pi, oh-my-opencode-slim, Go). # # The two published variants are produced from THIS Dockerfile by # varying build args: # # variant INSTALL_OPENCODE INSTALL_OMOS # ──────── ──────────────── ──────────── # base true false # omos true true # # pi was removed in v2.0.0 (it had been deprecated since v1.17.2). It now # ships from its own self-contained image: joakimp/pi-devbox:latest # (https://gitea.jordbo.se/joakimp/pi-devbox). See docs/CLEANUP-v2.0.0.md # for the removal history. # # Pass `--build-arg BASE_IMAGE=:base-` to select the base. # The CI workflow computes the base hash from Dockerfile.base + rootfs/ # + entrypoint*.sh and feeds it in. # # IMPORTANT: the base image sets NPM_CONFIG_PREFIX to # /home/developer/.config/opencode/npm-global so runtime `npm install -g` # by the developer user lands on the named volume. At BUILD time we want # the baked binaries on /usr so they survive the volume mount. Each # `npm install -g` below therefore prefixes the command with # `NPM_CONFIG_PREFIX=/usr`. ARG BASE_IMAGE FROM ${BASE_IMAGE} ARG TARGETARCH ARG USER_NAME=developer # ── Install opencode via npm ───────────────────────────────────────── # OPENCODE_VERSION is intentionally pinned in this Dockerfile (not # 'latest'). It drives the release tag and gets bumped via a source # edit, so the cache-hit class of bug that bit pi-devbox v0.74.0.. # v0.75.5 cannot apply here. ARG INSTALL_OPENCODE=true ARG OPENCODE_VERSION=1.17.4 RUN if [ "${INSTALL_OPENCODE}" = "true" ]; then \ NPM_CONFIG_PREFIX=/usr npm install -g opencode-ai@${OPENCODE_VERSION} && \ opencode --version ; \ fi # ── Optional: Go ───────────────────────────────────────────────────── ARG INSTALL_GO=false ARG GO_VERSION=latest RUN if [ "${INSTALL_GO}" = "true" ]; then \ GOARCH=$(case "${TARGETARCH}" in amd64) echo "amd64" ;; arm64) echo "arm64" ;; *) echo "amd64" ;; esac) && \ V="${GO_VERSION}" && \ if [ "$V" = "latest" ]; then \ V=$(curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://go.dev/dl/?mode=json" | \ awk -F'"' '/"version":/ { sub(/^go/,"",$4); print $4; exit }'); \ fi && \ [ -n "$V" ] && \ echo "Installing Go ${V}" && \ curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://go.dev/dl/go${V}.linux-${GOARCH}.tar.gz" | tar -C /usr/local -xz && \ ln -s /usr/local/go/bin/go /usr/local/bin/go && \ ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt; \ fi # ── Optional: oh-my-opencode-slim (multi-agent orchestration) ──────── # Installs Bun runtime and the oh-my-opencode-slim npm package. # OMOS_VERSION has a cache-hit footgun when left at the `latest` default # in registry-cached CI builds: the resulting build-arg string is byte- # identical across builds, so the layer-hash is identical, so the # registry buildcache silently reuses the layer from whatever omos # version was current when the cache was first populated. CI resolves it # via `npm view oh-my-opencode-slim version` and passes the concrete # value as a build-arg (see resolve-versions in docker-publish-split.yml). ARG INSTALL_OMOS=false ARG OMOS_VERSION=latest RUN if [ "${INSTALL_OMOS}" = "true" ]; then \ ARCH=$(uname -m) && \ if [ "$ARCH" = "x86_64" ]; then \ BUN_ARCH="x64-baseline"; \ elif [ "$ARCH" = "aarch64" ]; then \ BUN_ARCH="aarch64"; \ fi && \ curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://github.com/oven-sh/bun/releases/latest/download/bun-linux-${BUN_ARCH}.zip" -o /tmp/bun.zip && \ unzip -o /tmp/bun.zip -d /tmp/bun && \ mv /tmp/bun/bun-linux-${BUN_ARCH}/bun /usr/local/bin/bun && \ chmod +x /usr/local/bin/bun && \ ln -sf bun /usr/local/bin/bunx && \ rm -rf /tmp/bun /tmp/bun.zip && \ bun --version && \ test -L /usr/local/bin/bunx && \ NPM_CONFIG_PREFIX=/usr npm install -g oh-my-opencode-slim@${OMOS_VERSION}; \ fi # WORKDIR / ENTRYPOINT / CMD inherited from base.