96b84eb84d
One image — `bot-bottle-sidecars:latest`, built from `Dockerfile.sidecars` — served two unrelated roles: the egress/git-gate/supervise *data plane* and the orchestrator *control plane* (which ran the same image with the entrypoint overridden to `python3 -m bot_bottle.orchestrator`). The control plane is stdlib-only, so it needed none of the mitmproxy/git/gitleaks payload it was riding on — while being the most secret-dense process on the host (PRD 0070's "secret concentration"). Split into two purpose-built images: - `Dockerfile.gateway` -> `bot-bottle-gateway:latest` — the data plane (renamed from Dockerfile.sidecars; identical contents). - `Dockerfile.orchestrator` -> `bot-bottle-orchestrator:latest` — a lean `python:3.12-slim` runtime; the bind-mounted `bot_bottle` package supplies the code (so the #381 source-hash recreate semantics are unchanged). `OrchestratorService` now takes distinct `image` (control plane, default `ORCHESTRATOR_IMAGE`) and `gateway_image` (data plane, default `GATEWAY_IMAGE`) instead of feeding one `self.image` to both, and builds the lean image (build-if-missing) before starting the container. The per-bottle bundle constants in `backend/docker/sidecar_bundle.py` now alias the gateway constants so a bundle and the shared gateway can never drift onto different images. The `bot-bottle-sidecars` *image* name and `Dockerfile.sidecars` are gone; the per-bottle *container* name prefix (`bot-bottle-sidecars-<slug>`) is intentionally left for a separate change. Verified end-to-end: both images build; the lean image runs the control plane; `ensure_running` brings up the orchestrator on `bot-bottle-orchestrator:latest` and the gateway on `bot-bottle-gateway:latest` (distinct images) and reports healthy. Closes #384. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
28 lines
1.3 KiB
Docker
28 lines
1.3 KiB
Docker
# Orchestrator control-plane image (PRD 0070, #384).
|
|
#
|
|
# The per-host orchestrator runs `python3 -m bot_bottle.orchestrator`.
|
|
# The `bot_bottle` package is **stdlib-only** by design, so the control
|
|
# plane needs nothing but a Python runtime — none of the gateway's
|
|
# mitmproxy / git / gitleaks payload (that is the separate
|
|
# `bot-bottle-gateway` image, Dockerfile.gateway). Splitting them keeps
|
|
# the secret-dense control plane (it concentrates every bottle's egress
|
|
# tokens — see PRD 0070's "secret concentration") on a minimal
|
|
# dependency surface.
|
|
#
|
|
# The repo is bind-mounted read-only into the container at run time (see
|
|
# `orchestrator/lifecycle.py`), so the source is NOT copied in here: the
|
|
# image is just the runtime. `ensure_running` recreates the container
|
|
# only when the bind-mounted source hash changes (#381), which is why
|
|
# the code stays a mount rather than a baked layer.
|
|
|
|
FROM python:3.12-slim
|
|
|
|
# No third-party deps to install — stdlib only. Kept as an explicit,
|
|
# self-documenting stage so a future confinement step (baking the
|
|
# package, dropping the bind mount) has an obvious home.
|
|
WORKDIR /app
|
|
|
|
# Documentation only; lifecycle.py overrides the entrypoint to
|
|
# `python3 -m bot_bottle.orchestrator` with the runtime flags.
|
|
ENTRYPOINT ["python3", "-m", "bot_bottle.orchestrator"]
|