Spaces:
Running
Running
| # ══════════════════════════════════════════════════════════════════════════════ | |
| # Aegis-ML — Multi-stage Docker build using UV | |
| # Target image: ~600 MB (base deps only, no HF/torch) | |
| # ~2.5 GB with HF extra | |
| # | |
| # Build: | |
| # docker build -t aegis-ml . | |
| # docker build --build-arg EXTRAS=hf -t aegis-ml:hf . | |
| # | |
| # Run: | |
| # docker run -p 8000:8000 -e CLASSIFIER_TYPE=sklearn aegis-ml | |
| # ══════════════════════════════════════════════════════════════════════════════ | |
| # ── Stage 1: UV + dependency resolver ───────────────────────────────────────── | |
| FROM ghcr.io/astral-sh/uv:0.5 AS uv-base | |
| # ── Stage 2: Python builder (compile all deps) ──────────────────────────────── | |
| FROM python:3.11-slim-bookworm AS builder | |
| # Install system build deps (needed by some Python packages with C extensions) | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| gcc g++ build-essential libffi-dev libssl-dev curl \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Copy UV binary from the official UV image | |
| COPY --from=uv-base /uv /usr/local/bin/uv | |
| COPY --from=uv-base /uvx /usr/local/bin/uvx | |
| WORKDIR /build | |
| # Copy only dependency files first (layer cache optimisation) | |
| COPY pyproject.toml ./ | |
| # Which optional extras to install (default: base only; override with --build-arg EXTRAS=hf) | |
| ARG EXTRAS="" | |
| # Install dependencies into a venv using UV | |
| # --mount=type=cache speeds up repeated builds by caching the UV download cache | |
| RUN --mount=type=cache,target=/root/.cache/uv \ | |
| if [ -z "$EXTRAS" ]; then \ | |
| uv venv /app/.venv && \ | |
| uv pip install --python /app/.venv/bin/python .; \ | |
| else \ | |
| uv venv /app/.venv && \ | |
| uv pip install --python /app/.venv/bin/python ".[$EXTRAS]"; \ | |
| fi | |
| # ── Stage 3: Final slim runtime image ───────────────────────────────────────── | |
| FROM python:3.11-slim-bookworm AS runtime | |
| # Non-root user for security | |
| RUN useradd --create-home --shell /bin/bash aegis | |
| # Minimal runtime system deps | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| curl \ | |
| && rm -rf /var/lib/apt/lists/* | |
| WORKDIR /app | |
| # Copy the pre-built venv from builder stage | |
| COPY --from=builder /app/.venv /app/.venv | |
| # Copy application source | |
| COPY --chown=aegis:aegis app/ ./app/ | |
| COPY --chown=aegis:aegis demo/ ./demo/ | |
| COPY --chown=aegis:aegis training/ ./training/ | |
| COPY --chown=aegis:aegis pyproject.toml ./ | |
| # Create required directories | |
| RUN mkdir -p /app/models /app/logs /app/data && \ | |
| chown -R aegis:aegis /app/models /app/logs /app/data | |
| # Use the venv's Python exclusively | |
| ENV PATH="/app/.venv/bin:$PATH" | |
| ENV PYTHONPATH="/app" | |
| ENV PYTHONDONTWRITEBYTECODE=1 | |
| ENV PYTHONUNBUFFERED=1 | |
| # Default environment (override via docker-compose or -e flags) | |
| ENV HOST=0.0.0.0 | |
| ENV PORT=8000 | |
| ENV CLASSIFIER_TYPE=sklearn | |
| ENV CONFIDENCE_THRESHOLD=0.70 | |
| ENV LOG_LEVEL=INFO | |
| USER aegis | |
| EXPOSE 8000 | |
| EXPOSE 7860 | |
| # Health check — verify the /health endpoint is responsive | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \ | |
| CMD curl -f http://localhost:${PORT}/health || exit 1 | |
| # Default command: run the FastAPI service | |
| CMD ["python", "-m", "uvicorn", "app.main:app", \ | |
| "--host", "0.0.0.0", \ | |
| "--port", "8000", \ | |
| "--workers", "1", \ | |
| "--log-level", "info"] | |