# The harness host. Build from the repository root, with the version from git (the build context has no .git):
#   docker build -f packages/harness-host/Dockerfile -t harness-host \
#     --build-arg HARNESS_VERSION="$(uv run python scripts/versions.py python)" .
# Dependencies come from uv.lock with their hashes, so the image has exactly the packages the tests ran with. The image
# includes the telemetry extra: set OTEL_EXPORTER_OTLP_ENDPOINT to export traces and metrics (contract §13). It also
# includes harness-servers, so HARNESS_MCP_CONFIG can start them over stdio, e.g. the web server with web search (#17):
#   {"servers": [{"name": "web", "command": "python", "args": ["-m", "harness_servers.web"],
#                 "env": {"HARNESS_SEARCH_BACKEND": "searxng", "HARNESS_SEARCH_URL": "http://searxng:8080",
#                         "HARNESS_WEB_CONTACT": "https://chat.example.org"}}]}

# The base images by digest (#153): a build gets the same bases on every machine, whatever its daemon holds.
ARG PYTHON_IMAGE=python:3.12-slim-bookworm@sha256:935c3c5b12357a7e10caa9c1e6ca5692344d97cf229832ef584be2cec9fc03df
ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.9.10@sha256:29bd45092ea8902c0bbb7f0a338f0494a382b1f4b18355df5be270ade679ff1d

FROM ${UV_IMAGE} AS uv

FROM ${PYTHON_IMAGE} AS build
COPY --from=uv /uv /usr/local/bin/uv
ARG HARNESS_VERSION
RUN test -n "$HARNESS_VERSION" || (echo "pass --build-arg HARNESS_VERSION (scripts/versions.py python)" && exit 1)
# hatch-vcs reads the version from git; without .git it takes this one.
ENV SETUPTOOLS_SCM_PRETEND_VERSION=${HARNESS_VERSION}
WORKDIR /src
COPY pyproject.toml uv.lock ./
COPY packages ./packages
COPY servers ./servers
COPY samples ./samples
RUN mkdir -p /out \
 && uv export --frozen --no-dev --package knurz-harness-host --package knurz-harness-servers --extra telemetry --no-emit-workspace -o /out/requirements.txt \
 && uv build --package knurz-harness --wheel --out-dir /out/wheels \
 && uv build --package knurz-harness-host --wheel --out-dir /out/wheels \
 && uv build --package knurz-harness-servers --wheel --out-dir /out/wheels

FROM ${PYTHON_IMAGE}
RUN useradd --uid 10001 --create-home --shell /usr/sbin/nologin harness
# The dependencies first, checked against the hashes of uv.lock: this layer stays cached while only the code changes.
COPY --from=build /out/requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir --require-hashes -r /tmp/requirements.txt \
 && rm /tmp/requirements.txt
COPY --from=build /out/wheels /tmp/wheels
RUN pip install --no-cache-dir --no-deps /tmp/wheels/*.whl \
 && rm -rf /tmp/wheels
USER 10001
ENV HARNESS_HOST_BIND=0.0.0.0 \
    HARNESS_HOST_PORT=8080 \
    PYTHONUNBUFFERED=1
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD ["python", "-c", "import os, sys, urllib.request; port = os.environ.get('HARNESS_HOST_PORT', '8080'); sys.exit(urllib.request.urlopen(f'http://127.0.0.1:{port}/v1/status', timeout=3).status != 200)"]
# The version and the commit last: every commit changes them, and a layer after them would be built again each time.
ARG HARNESS_VERSION
ARG HARNESS_REVISION=unknown
LABEL org.opencontainers.image.title="harness-host" \
      org.opencontainers.image.version="${HARNESS_VERSION}" \
      org.opencontainers.image.revision="${HARNESS_REVISION}" \
      org.opencontainers.image.source="https://git.knurz.com/developer/harness" \
      org.opencontainers.image.licenses="LicenseRef-Proprietary"
CMD ["harness-host"]
