Baked installs had two failure modes: anything installed into $HOME at build time is shadowed by the container-home bind mount at runtime, and system-wide installs are root-owned, so the tools' own update commands (pi update, claude update, opencode upgrade) failed with an unwritable install path. With pi releasing new versions almost daily, the only remedy, a full image rebuild that also deleted every container, was too heavy for that cadence. Now each tool is installed at runtime into the persistent container home by its official installer (no sudo), the same way the Docker image itself is built on first use. Self-updates work inside the container and survive image rebuilds and container recreation. The image shrinks to a plain Arch base, and agent-container update no longer removes containers, so sudo-installed project dependencies survive it too. docker exec now attaches a TTY only when stdin is one, so scripted runs like 'pi -p' work without a terminal.
33 lines
1 KiB
Docker
33 lines
1 KiB
Docker
FROM archlinux:latest
|
|
|
|
ARG USERNAME=dev
|
|
ARG UID=1000
|
|
ARG GID=1000
|
|
|
|
RUN pacman -Syu --noconfirm \
|
|
base-devel \
|
|
git \
|
|
ca-certificates \
|
|
bash \
|
|
less \
|
|
ripgrep \
|
|
nodejs \
|
|
npm \
|
|
curl \
|
|
sudo && \
|
|
groupadd -g ${GID} ${USERNAME} && \
|
|
useradd -m -u ${UID} -g ${GID} -s /bin/bash ${USERNAME} && \
|
|
echo "${USERNAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
|
|
pacman -Scc --noconfirm
|
|
|
|
# OpenCode, Claude Code, and Pi are intentionally NOT baked into the image:
|
|
# an install into $HOME at build time would be shadowed by the container-home
|
|
# bind mount, and system-wide installs are root-owned and not self-updatable.
|
|
# On first use, agent-container.py runs each tool's official installer (no
|
|
# sudo) against the persistent container home instead, so `pi update`,
|
|
# `claude update`, and `opencode upgrade` work inside the container and
|
|
# survive image rebuilds and container recreation. See _bootstrap_tool() in
|
|
# agent-container.py.
|
|
USER ${USERNAME}
|
|
|
|
WORKDIR /home/${USERNAME}
|