# syntax=docker/dockerfile:1 FROM python:3.12-slim ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ UV_PROJECT_ENVIRONMENT=/opt/venv \ PATH=/opt/venv/bin:$PATH # LightGBM links against OpenMP at runtime (libgomp.so.1). The python:3.12-slim # base image does not ship it, so we install it explicitly. Note: packages.txt # is ignored by HF Spaces when sdk=docker — system deps must live here. RUN apt-get update \ && apt-get install -y --no-install-recommends libgomp1 \ && rm -rf /var/lib/apt/lists/* # UV gives reproducible installs from uv.lock and is faster than pip. COPY --from=ghcr.io/astral-sh/uv:0.5.4 /uv /usr/local/bin/uv WORKDIR /app # Resolve runtime deps first so the layer is cached when only source code # changes. COPY pyproject.toml uv.lock ./ RUN uv sync --frozen --no-dev --no-install-project # Application code + serialized artefacts. The 235 MB feature store is NOT # bundled — it lives in a separate HF Dataset repo and is fetched at runtime # via huggingface_hub (see api/main.py::_resolve_feature_store_path). COPY api/ ./api/ COPY database/ ./database/ COPY models/ ./models/ # Sanity: fail fast at build time if the artefacts the API needs are missing. RUN test -f models/model.joblib \ && test -f models/feature_names.json \ && test -f models/app_train_categories.json \ && test -f models/app_train_binary_mappings.json \ && test -f models/no_history_template.json \ && echo "All runtime artefacts present." EXPOSE 7860 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD python -c "import urllib.request, sys; \ sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:7860/health').status == 200 else 1)" CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "7860"]