precis / Dockerfile
compendious's picture
GPU speedup
4a6590d unverified
Raw History Blame Contribute Delete
3.47 kB
# syntax=docker/dockerfile:1
# ── Stage 1: Build frontend ──────────────────────────────────────────────
FROM node:20-alpine AS frontend-builder
WORKDIR /app/frontend
# Leverage Docker cache: only reinstall when deps change
COPY frontend/package.json frontend/package-lock.json* ./
RUN --mount=type=cache,target=/root/.npm npm ci --prefer-offline --no-audit --no-fund || npm install --no-audit --no-fund
COPY frontend ./
# Build-time env: API_BASE empty = same origin (FastAPI serves frontend)
# These are baked at `npm run build` time — BE CAREFUL with secrets.
# VITE_API_KEY is intentionally baked so the browser can auth without extra config.
ARG VITE_API_BASE_URL=""
ARG PRECIS_API_KEY=""
ARG VITE_API_KEY=""
ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}
ENV PRECIS_API_KEY=${PRECIS_API_KEY}
ENV VITE_API_KEY=${VITE_API_KEY}
RUN npm run build
# ── Stage 2: Python runtime via conda env `precis` ──────────────────────
# NOTE: This stage is heavy (~2GB) because `environment.yml` includes torch/transformers
# for training. For production API only, you could use `python:3.11-slim` + `pip install -r requirements.txt`
# with a minimal runtime requirements file. We keep conda for parity with local dev.
FROM continuumio/miniconda3:latest
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \
NODE_ENV=production \
CONDA_AUTO_UPDATE_CONDA=false
# curl for healthchecks
RUN apt-get update && apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Create the `precis` env exactly as you do locally:
# conda env create -f environment.yml (or `conda create -n precis python=3.11 && pip install -r requirements.txt`)
COPY environment.yml requirements.txt ./
# Use BuildKit cache for conda pkgs to reduce 4-6min rebuilds
RUN --mount=type=cache,target=/opt/conda/pkgs conda env create -f environment.yml && conda clean -afy
# Make `precis` the default Python for all subsequent layers + runtime
ENV CONDA_DEFAULT_ENV=precis
ENV CONDA_PREFIX=/opt/conda/envs/precis
ENV PATH=/opt/conda/envs/precis/bin:$PATH
# Verify the env (fails fast if not created)
RUN which python && python --version && conda run -n precis python -c "import fastapi, httpx; print('precis env ready')"
# Copy backend flattened to /app so `from config import ...` works with `uvicorn app:app`
COPY backend ./
# Bring built frontend to where app.py expects it: /app/frontend/dist
COPY --from=frontend-builder /app/frontend/dist ./frontend/dist
# HF Spaces expects 7860, local dev uses 8000 — expose both.
# At runtime HF sets $PORT=7860; locally defaults to 8000 via ENV PORT.
EXPOSE 8000 7860
ENV PORT=8000 \
OLLAMA_BASE_URL=http://host.docker.internal:11434 \
DEFAULT_MODEL=phi4-mini:latest \
AVAILABLE_MODELS=phi4-mini:latest \
PRECIS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:8000,http://localhost:7860,https://*.hf.space,https://*.huggingface.co
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD curl -fsS http://localhost:${PORT:-8000}/health || curl -fsS http://localhost:8000/health || curl -fsS http://localhost:7860/health || exit 1
# Uses precis env via PATH; shell form expands $PORT (HF sets 7860, local uses 8000)
CMD ["sh", "-c", "uvicorn app:app --host 0.0.0.0 --port ${PORT:-8000}"]