# Hosted-agent container (Fase 4d). Build context is `git archive HEAD` — what a stranger # actually downloads, never the working tree — and the hosting platform requires x86_64 # (spike §1.4), so the measured build command is: # # git archive HEAD | docker build --platform linux/amd64 -t portfolio-optimiser - # # Base: the version pinned by .python-version (3.12), mid-band of the resolution matrix # (3.10–3.13 have numpy wheels, 3.14 does not — spike §4), and the same base Microsoft's # own MAF sample uses. Runs as root like that sample: no non-root requirement is # documented (spike, Ikke verifisert pkt. 7). FROM python:3.12-slim-bookworm # git: the two security components are git-tag-pinned direct references, and # [tool.uv.sources] never reaches wheel metadata (spike §3/§7.2) — uv needs the git CLI # to fetch them, and -slim ships without it. RUN apt-get update \ && apt-get install -y --no-install-recommends git \ && rm -rf /var/lib/apt/lists/* # Pinned to the uv the tree was measured with (13.08) — an unpinned installer would let # the container's resolver drift from the working tree's. RUN pip install --no-cache-dir uv==0.9.8 WORKDIR /app COPY . . # The LOCKED, dev-free environment — the same resolution the working tree was measured # with (agent-framework-core 1.9.0). Never a fresh resolve from pyproject.toml: that # picks other versions (1.13.0) than every measurement in this repo ran against (§3). RUN uv sync --frozen --no-dev # The hosted-agent runtime contract: port 8088, GET /readiness, POST /invocations, # SIGTERM shutdown (spike §1.1) — served by main.py (portfolio_optimiser.hosting). EXPOSE 8088 CMD ["/app/.venv/bin/python", "main.py"]