# ── Stage 1: dependency install ──────────────────────────────────────────────── FROM python:3.11-slim AS deps WORKDIR /app # System packages needed at build time only (git for any VCS deps, curl for health check) RUN apt-get update && \ apt-get install -y --no-install-recommends git curl && \ rm -rf /var/lib/apt/lists/* # Copy dependency manifests first so Docker can cache this layer # and skip re-installing when only source code changes COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir -r requirements.txt # ── Stage 2: runtime image ───────────────────────────────────────────────────── FROM python:3.11-slim AS runtime # curl is needed for the HEALTHCHECK RUN apt-get update && \ apt-get install -y --no-install-recommends curl && \ rm -rf /var/lib/apt/lists/* # Create a non-root user — required by Hugging Face Spaces RUN useradd -m -u 1000 appuser WORKDIR /app # Copy installed packages from the build stage (no venv needed inside Docker) COPY --from=deps /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY --from=deps /usr/local/bin /usr/local/bin # Copy the entire my_env package # Build context must be the my_env/ directory (see README for docker build command) COPY --chown=appuser:appuser . /app # PYTHONPATH makes `import my_env` and `import server` both resolve correctly ENV PYTHONPATH="/app" # HF Spaces requires port 7860. Internal uvicorn also binds 7860. EXPOSE 7860 # Health check — HF Spaces polls /health to decide if the container is ready HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=5 \ CMD curl -f http://localhost:7860/health || exit 1 USER appuser # Run from /app/my_env so relative imports (server.app:app) resolve correctly WORKDIR /app ENV ENABLE_WEB_INTERFACE=true CMD ["uvicorn", "server.app:app", \ "--host", "0.0.0.0", \ "--port", "7860", \ "--workers", "1", \ "--log-level", "info"]