# Gateway data-plane image (PRD 0024 bundle shape; PRD 0070 gateway). # # The egress / git-gate / supervise *data plane* — one image, run by # the consolidated per-host gateway (PRD 0070). It is NOT the # orchestrator control plane: that is the separate, lean # `bot-bottle-orchestrator` image (Dockerfile.orchestrator, #384), which # ships only python + the stdlib-only `bot_bottle` package and none of # this image's mitmproxy / git / gitleaks payload. # # Collapses the prior per-daemon images (egress, git-gate, # supervise) into one. A small stdlib-Python init supervisor at # /app/gateway_init.py spawns all daemons, forwards SIGTERM, and # propagates per-daemon stdout/stderr to the container log with a # `[name]` prefix. See PRD 0024 for the rationale. # # Layout: # # /usr/bin/gitleaks gitleaks binary # /app/egress_addon.py + siblings mitmproxy addon (egress) # /app/egress-entrypoint.sh mitmdump launcher # /app/supervise_server.py + .py supervise MCP server # /app/gateway_init.py PID 1 supervisor # /etc/egress/routes.yaml bind-mounted at run time # /etc/git-gate/pre-receive docker-cp'd at start time # /git-gate-entrypoint.sh docker-cp'd at start time # /git-gate/creds/* docker-cp'd at start time # /git/* bare repos, populated at runtime # /run/supervise/bot-bottle.db bind-mounted at run time # /home/mitmproxy/.mitmproxy/ mitmproxy CA dir # # Exposed ports inside the container: # 9099 egress (mitmproxy, agent-facing HTTPS proxy) # 9418 git-gate (git-daemon) # 9420 git-gate smart HTTP (VM-backend agent-facing transport) # 9100 supervise (MCP HTTP) # Based on `python:3.12-slim` (Debian trixie) rather than the # `mitmproxy/mitmproxy` image (Debian bookworm) so the whole stack — # gateway here, and the firecracker infra image that builds FROM this — # lands on trixie, whose buildah (1.39) can build agent Dockerfiles that # use heredocs. mitmproxy is pip-installed to the same effect as the # upstream image. (bookworm's buildah is 1.28, which can't parse # `RUN ... <&2; exit 1 ;; \ esac \ && url="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_${asset}.tar.gz" \ && python3 -c "import sys,urllib.request; urllib.request.urlretrieve(sys.argv[1], '/tmp/gitleaks.tar.gz')" "$url" \ && echo "${sha} /tmp/gitleaks.tar.gz" | sha256sum -c - \ && tar -xzf /tmp/gitleaks.tar.gz -C /usr/bin gitleaks \ && rm /tmp/gitleaks.tar.gz # Project Python: addon + server modules + the init supervisor. # Kept flat under /app/ so mitmdump's loader resolves them as # top-level siblings (absolute imports), matching the prior # Dockerfile.egress / Dockerfile.supervise layout. COPY bot_bottle/egress_addon_core.py /app/egress_addon_core.py COPY bot_bottle/egress_dlp_config.py /app/egress_dlp_config.py COPY bot_bottle/egress_addon.py /app/egress_addon.py COPY bot_bottle/policy_resolver.py /app/policy_resolver.py COPY bot_bottle/dlp_detectors.py /app/dlp_detectors.py COPY bot_bottle/yaml_subset.py /app/yaml_subset.py COPY bot_bottle/paths.py /app/paths.py COPY bot_bottle/migrations.py /app/migrations.py COPY bot_bottle/db_store.py /app/db_store.py COPY bot_bottle/supervise_types.py /app/supervise_types.py COPY bot_bottle/queue_store.py /app/queue_store.py COPY bot_bottle/audit_store.py /app/audit_store.py COPY bot_bottle/store_manager.py /app/store_manager.py COPY bot_bottle/supervise.py /app/supervise.py COPY bot_bottle/supervise_server.py /app/supervise_server.py COPY bot_bottle/gateway_init.py /app/gateway_init.py COPY bot_bottle/git_http_backend.py /app/git_http_backend.py COPY bot_bottle/egress_entrypoint.sh /app/egress-entrypoint.sh RUN chmod +x /app/egress-entrypoint.sh # Pre-create runtime directories the compose renderer + start # step expect to exist. `docker cp` does not create intermediate # dirs, and bind mounts won't either if the parent is missing. RUN mkdir -p \ /etc/egress \ /etc/git-gate \ /git-gate/creds \ /git \ /run/supervise \ /home/mitmproxy/.mitmproxy # Documentation only — the compose renderer publishes whichever # subset the bottle uses. EXPOSE 8888 9099 9418 9420 9100 # WORKDIR matches Dockerfile.supervise's prior layout so the # in-app same-dir import in supervise_server.py stays deterministic. WORKDIR /app # PID 1 is the supervisor. It owns signal handling and exit-code # propagation; no `exec` chain in the entrypoint itself. ENTRYPOINT ["python3", "/app/gateway_init.py"]