refactor: re-brand the opencode-devbox with-pi variant (single source of truth)
pi-devbox no longer installs pi itself. The Dockerfile is now a thin FROM joakimp/opencode-devbox:latest-with-pi (overridable via BASE_IMAGE), inheriting pi + pi-toolkit + pi-extensions + pi-fork (fork) + pi-observational-memory (recall) + the LAN-access helper + all base tooling from the single source of truth. Eliminates the install-logic duplication that drifted against opencode-devbox/Dockerfile.variant (decision #3). Consequences (documented in CHANGELOG/AGENTS): - The image now ALSO contains opencode (with-pi has INSTALL_OPENCODE=true). A leaner pi-only image would need a dedicated pi-only variant upstream. - Publish ordering: release opencode-devbox first so latest-with-pi carries the target pi version, THEN tag this repo. The smoke test asserts pi --version matches the tag (EXPECTED_PI_VERSION) and fails loudly if the base is stale — turning the version coupling into an enforced ordering guard. CI: drop PI_VERSION build-arg (Dockerfile installs nothing); keep tag->version resolution to feed the smoke base-freshness guard. Smoke adds fork/recall clone + node_modules + settings.json registration checks; size threshold 2200 -> 2900 MB (now tracks with-pi). Docs updated across README, AGENTS, DOCKER_HUB, .env.example, docker-compose.
This commit is contained in:
+24
-56
@@ -1,62 +1,30 @@
|
||||
# pi-devbox — pi coding-agent container
|
||||
#
|
||||
# Builds on top of the opencode-devbox base image, which provides:
|
||||
# Debian trixie, Node.js, AWS CLI, mempalace + MCP server, gitea-mcp,
|
||||
# dev tools (neovim, tmux, bat, eza, fzf, zoxide, ripgrep, uv, rustup,
|
||||
# git-crypt, gitleaks),
|
||||
# user setup (developer/gosu), entrypoints, chromadb prewarm.
|
||||
# As of 2026-06-03 this image is a thin re-brand of the opencode-devbox
|
||||
# "with-pi" variant, which is the SINGLE SOURCE OF TRUTH for the pi install
|
||||
# and its companion repos (pi-toolkit, pi-extensions, pi-fork,
|
||||
# pi-observational-memory). Previously pi-devbox/Dockerfile duplicated that
|
||||
# install logic, which drifted from opencode-devbox/Dockerfile.variant; this
|
||||
# refactor eliminates the duplication.
|
||||
#
|
||||
# This image adds only pi itself and its companion repos.
|
||||
# Everything is inherited from the with-pi image:
|
||||
# pi + pi-toolkit + pi-extensions + pi-fork (fork) + pi-observational-memory
|
||||
# (recall), the mempalace bridge, the LAN-access helper, entrypoints, and
|
||||
# all base dev tooling.
|
||||
#
|
||||
# Build args:
|
||||
# BASE_IMAGE — base image to build from (default: base-latest)
|
||||
# PI_VERSION — pi npm version: "latest" or a pinned version e.g. "0.74.0"
|
||||
# PI_TOOLKIT_REF — git ref for pi-toolkit (default: main)
|
||||
# PI_EXTENSIONS_REF — git ref for pi-extensions (default: main)
|
||||
|
||||
ARG BASE_IMAGE=joakimp/opencode-devbox:base-latest
|
||||
# NOTES / consequences of FROM-ing with-pi:
|
||||
# - This image now ALSO contains opencode (with-pi has INSTALL_OPENCODE=true).
|
||||
# If a leaner pi-only image is wanted later, add a dedicated pi-only variant
|
||||
# to opencode-devbox and FROM that instead.
|
||||
# - PUBLISH ORDERING: rebuild opencode-devbox (so `latest-with-pi` carries the
|
||||
# target pi version) BEFORE tagging this repo. The smoke test asserts
|
||||
# `pi --version` matches this repo's tag and fails loudly if the base is
|
||||
# stale — turning the version coupling into an enforced ordering check.
|
||||
#
|
||||
# Override BASE_IMAGE to pin a specific with-pi build (e.g. a version tag or a
|
||||
# digest) instead of tracking latest-with-pi.
|
||||
ARG BASE_IMAGE=joakimp/opencode-devbox:latest-with-pi
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
# PI_VERSION should be passed explicitly by CI as a concrete version
|
||||
# (e.g. PI_VERSION=0.75.5, derived from the git tag). The default `latest`
|
||||
# is for local dev convenience only — it has a known cache-hit footgun
|
||||
# when used in registry-cached CI builds. See .gitea/workflows/docker-
|
||||
# publish.yml § "Resolve PI_VERSION from tag" and AGENTS.md gotcha for
|
||||
# the full story (silent same-bytes-across-releases regression discovered
|
||||
# 2026-05-23 affecting all builds v0.74.0..v0.75.5).
|
||||
ARG PI_VERSION=0.78.0
|
||||
ARG PI_TOOLKIT_REF=main
|
||||
ARG PI_EXTENSIONS_REF=main
|
||||
|
||||
# Install pi and clone companion repos.
|
||||
# NPM_CONFIG_PREFIX is overridden to /usr so the baked binary lands at the
|
||||
# system prefix — same pattern as opencode-devbox's variant Dockerfile.
|
||||
# At runtime, NPM_CONFIG_PREFIX is reset to /home/developer/.pi/npm-global
|
||||
# (inherited from base ENV) so user-installed packages land on the named
|
||||
# volume and survive container recreate.
|
||||
#
|
||||
# git clone is wrapped in a retry loop because gitea.jordbo.se occasionally
|
||||
# returns transient HTTP 500s on the first request after idle.
|
||||
RUN set -e && \
|
||||
git_clone_retry() { \
|
||||
url="$1"; ref="$2"; dest="$3"; \
|
||||
for i in 1 2 3 4 5; do \
|
||||
if git clone --depth 1 --branch "$ref" "$url" "$dest"; then return 0; fi; \
|
||||
rm -rf "$dest"; \
|
||||
echo "git clone $url failed (attempt $i/5), retrying in $((i*5))s..."; \
|
||||
sleep $((i*5)); \
|
||||
done; \
|
||||
return 1; \
|
||||
} && \
|
||||
if [ "${PI_VERSION}" = "latest" ]; then \
|
||||
NPM_CONFIG_PREFIX=/usr npm install -g @earendil-works/pi-coding-agent ; \
|
||||
else \
|
||||
NPM_CONFIG_PREFIX=/usr npm install -g @earendil-works/pi-coding-agent@${PI_VERSION} ; \
|
||||
fi && \
|
||||
pi --version && \
|
||||
git_clone_retry https://gitea.jordbo.se/joakimp/pi-toolkit.git "${PI_TOOLKIT_REF}" /opt/pi-toolkit && \
|
||||
git_clone_retry https://gitea.jordbo.se/joakimp/pi-extensions.git "${PI_EXTENSIONS_REF}" /opt/pi-extensions && \
|
||||
echo "pi-toolkit at $(cd /opt/pi-toolkit && git rev-parse --short HEAD)" && \
|
||||
echo "pi-extensions at $(cd /opt/pi-extensions && git rev-parse --short HEAD)"
|
||||
|
||||
# WORKDIR / ENTRYPOINT / CMD inherited from base.
|
||||
# WORKDIR / ENTRYPOINT / CMD and all tooling inherited from the base.
|
||||
# No additional layers — the value here is the single-source-of-truth refactor.
|
||||
|
||||
Reference in New Issue
Block a user