refactor(docker): consolidated build into pi-base + pi-runtime stages
- Replaced the slim artifacts-only image with a full pi-base image (python + bun + rustup + natives + omp_rpc + omp shim). - Moved robomp Dockerfile to repo root as Dockerfile.robomp, extending pi-base instead of copying from a scratch artifacts image. - Renamed PI_ARTIFACTS_IMAGE to PI_BASE and updated all npm scripts and compose config accordingly. - Split .dockerignore into per-Dockerfile shadows (Dockerfile.dockerignore, Dockerfile.robomp.dockerignore).
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
.venv/
|
||||
.pi-context/
|
||||
data/
|
||||
*.pyc
|
||||
__pycache__/
|
||||
.pytest_cache/
|
||||
.git/
|
||||
.env
|
||||
*.sqlite
|
||||
*.sqlite-wal
|
||||
*.sqlite-shm
|
||||
web/node_modules/
|
||||
web/dist/
|
||||
src/static/
|
||||
node_modules/
|
||||
@@ -1,132 +0,0 @@
|
||||
# syntax=docker/dockerfile:1.7-labs
|
||||
###############################################################################
|
||||
# roboomp — orchestrator image
|
||||
#
|
||||
# Build is split across three stages:
|
||||
#
|
||||
# 1) pi-artifacts — pull a pre-built `oh-my-pi/artifacts:dev` image (built
|
||||
# separately from /work/pi/Dockerfile, see `bun run robomp:pi-artifacts`):
|
||||
# - pi_natives.linux-<arch>.node → /opt/bun/bin/ (the pi loader probes here)
|
||||
# - omp_rpc-*.whl → pip install
|
||||
# 2) web-builder — Bun + Vite compile the SolidJS dashboard bundle from
|
||||
# the `web/` workspace into `web/dist/`.
|
||||
# 3) runtime — slim Python 3.12 image that copies in (1) the natives
|
||||
# + wheel, (2) the dashboard bundle, and (3) the roboomp source.
|
||||
#
|
||||
# At runtime the full pi checkout is mounted read-only at /work/pi so `omp`
|
||||
# (the Bun shim below) executes the coding-agent source directly. The image
|
||||
# itself stays slim: no rust compile, no pi source tree, no node_modules.
|
||||
###############################################################################
|
||||
|
||||
ARG PI_ARTIFACTS_IMAGE=oh-my-pi/artifacts:dev
|
||||
|
||||
############################
|
||||
# 1) pi-artifacts — pull the pre-built natives + omp-rpc wheel.
|
||||
############################
|
||||
FROM ${PI_ARTIFACTS_IMAGE} AS pi-artifacts
|
||||
|
||||
############################
|
||||
# 2) web-builder — Bun + Vite, builds the SolidJS dashboard bundle.
|
||||
############################
|
||||
FROM oven/bun:1.3.14-slim AS web-builder
|
||||
WORKDIR /work
|
||||
# Build context is the pi monorepo root, so the web-builder stage installs
|
||||
# from pi's bun.lock — that's how `web/package.json` resolves its `catalog:`
|
||||
# references against the workspace-wide catalog declared at pi root.
|
||||
COPY package.json bun.lock ./
|
||||
COPY python/robomp/web/package.json ./python/robomp/web/package.json
|
||||
RUN bun install --filter robomp-web
|
||||
COPY --exclude=node_modules --exclude=dist python/robomp/web/ ./python/robomp/web/
|
||||
RUN bun --cwd=python/robomp/web run build
|
||||
|
||||
############################
|
||||
# 3) runtime — slim image with everything roboomp needs at boot.
|
||||
############################
|
||||
FROM python:3.12-slim-bookworm AS runtime
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PIP_NO_CACHE_DIR=1 \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
||||
BUN_INSTALL=/opt/bun \
|
||||
PI_ROOT=/work/pi \
|
||||
# Persistent build caches under the /data volume so cargo target and
|
||||
# rustup toolchains are shared across every per-issue worktree and
|
||||
# survive container restarts. Bun's install cache is deliberately
|
||||
# workspace-private at runtime; bun chmod/chown behavior makes a shared
|
||||
# cross-slot cache unreliable.
|
||||
CARGO_HOME=/data/cache/cargo \
|
||||
CARGO_TARGET_DIR=/data/cache/cargo-target \
|
||||
RUSTUP_HOME=/data/cache/rustup \
|
||||
PATH=/opt/bun/bin:/usr/local/cargo/bin:/usr/local/bin:/usr/bin:/bin
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
git curl ca-certificates unzip openssh-client tini sqlite3 \
|
||||
build-essential pkg-config libssl-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG BUN_VERSION=1.3.14
|
||||
RUN curl -fsSL https://bun.sh/install | bash -s "bun-v${BUN_VERSION}" \
|
||||
&& /opt/bun/bin/bun --version
|
||||
|
||||
# Rustup launcher. Install the cargo/rustc/rustup proxies into a fixed
|
||||
# image path; the real toolchain is *not* baked in — it's installed
|
||||
# lazily into RUSTUP_HOME (=/data/cache/rustup) on the first `cargo`
|
||||
# invocation inside a worktree, driven by pi's rust-toolchain.toml.
|
||||
# That keeps the image small while sharing the toolchain across reboots.
|
||||
RUN curl -fsSL https://sh.rustup.rs -o /tmp/rustup-init.sh \
|
||||
&& CARGO_HOME=/usr/local/cargo RUSTUP_HOME=/usr/local/rustup-bootstrap \
|
||||
sh /tmp/rustup-init.sh -y --no-modify-path --default-toolchain none --profile minimal \
|
||||
&& rm -f /tmp/rustup-init.sh \
|
||||
&& rm -rf /usr/local/rustup-bootstrap \
|
||||
&& /usr/local/cargo/bin/rustup --version
|
||||
|
||||
# pi-natives addon: pi's loader probes /opt/bun/bin as a fallback path.
|
||||
COPY --from=pi-artifacts /out/pi_natives.linux-*.node /opt/bun/bin/
|
||||
|
||||
# omp-rpc Python wheel.
|
||||
COPY --from=pi-artifacts /out/*.whl /tmp/wheels/
|
||||
RUN pip install /tmp/wheels/omp_rpc-*.whl && rm -rf /tmp/wheels
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# `omp` shim — calls into the mounted pi checkout via Bun.
|
||||
RUN printf '%s\n' \
|
||||
'#!/usr/bin/env bash' \
|
||||
'set -euo pipefail' \
|
||||
': "${PI_ROOT:=/work/pi}"' \
|
||||
'if [ ! -d "$PI_ROOT/packages/coding-agent" ]; then' \
|
||||
' echo "roboomp: PI_ROOT=$PI_ROOT does not look like a pi checkout" >&2' \
|
||||
' exit 127' \
|
||||
'fi' \
|
||||
'exec bun "$PI_ROOT/packages/coding-agent/src/cli.ts" "$@"' \
|
||||
> /usr/local/bin/omp \
|
||||
&& chmod +x /usr/local/bin/omp
|
||||
|
||||
# roboomp itself. Drop the Vite-built dashboard into the package tree before
|
||||
# `pip install` so it lands in the installed wheel (`static/**/*` is declared
|
||||
# as package-data in pyproject.toml).
|
||||
COPY python/robomp/pyproject.toml ./
|
||||
COPY python/robomp/src/ ./src/
|
||||
COPY --from=web-builder /work/python/robomp/web/dist/ ./src/static/
|
||||
RUN pip install --upgrade pip \
|
||||
&& pip install \
|
||||
"fastapi>=0.112" "uvicorn[standard]>=0.30" "httpx>=0.27" \
|
||||
"pydantic>=2.6" "pydantic-settings>=2.2" "python-dotenv>=1.0" \
|
||||
"click>=8.1" \
|
||||
&& pip install --no-deps .
|
||||
|
||||
RUN mkdir -p /srv/agent-home/.agent /srv/agent-home/.omp/agent \
|
||||
&& mkdir -p /srv/agent-home-stage/.agent /srv/agent-home-stage/.omp/agent \
|
||||
&& printf '[install]\nbackend = "copyfile"\n' > /srv/agent-home/.bunfig.toml
|
||||
|
||||
COPY python/robomp/entrypoint.sh /usr/local/bin/robomp-entrypoint
|
||||
RUN chmod +x /usr/local/bin/robomp-entrypoint
|
||||
|
||||
VOLUME ["/data"]
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/robomp-entrypoint"]
|
||||
CMD ["python", "-m", "robomp", "serve"]
|
||||
@@ -13,13 +13,14 @@ services:
|
||||
build:
|
||||
# pi root: gives the web-builder stage access to the workspace
|
||||
# bun.lock + catalog (web/package.json refs `catalog:` versions).
|
||||
# python/robomp/data is excluded via pi's .dockerignore.
|
||||
# python/robomp/data and pi-root excludes are filtered via
|
||||
# Dockerfile.robomp.dockerignore at the context root.
|
||||
context: ../..
|
||||
dockerfile: python/robomp/Dockerfile
|
||||
dockerfile: Dockerfile.robomp
|
||||
args:
|
||||
# Tag of the pre-built artifacts image produced by `bun run robomp:pi-artifacts`
|
||||
# Tag of the pre-built pi-base image produced by `bun run pi:image`
|
||||
# (sources: pi root /Dockerfile). Override per-environment as needed.
|
||||
PI_ARTIFACTS_IMAGE: oh-my-pi/artifacts:dev
|
||||
PI_BASE: oh-my-pi/pi:dev
|
||||
image: robomp:dev
|
||||
container_name: robomp
|
||||
# Phase B (graceful shutdown): gives the orchestrator at least
|
||||
|
||||
Reference in New Issue
Block a user