# Multi-stage production Dockerfile for SentinelAI-RAG # Configured for Hugging Face Spaces (Docker SDK, 2 vCPU, 16GB RAM, Port 7860, UID 1000) & Render # Stage 1: Build C++17 SIMD extension & Python dependencies FROM python:3.12-slim AS builder WORKDIR /build # Install C++17 build tools & SIMD support RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ g++ \ cmake \ git \ && rm -rf /var/lib/apt/lists/* # Install slim CPU-only PyTorch first (avoids pulling 2GB CUDA binaries) RUN pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu # Install remaining Python build dependencies COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Compile C++17 AVX2 SIMD engine COPY cpp_engine/ ./cpp_engine/ WORKDIR /build/cpp_engine RUN python setup.py build_ext --inplace # Stage 2: Production runtime stage FROM python:3.12-slim AS runtime # Install runtime system packages RUN apt-get update && apt-get install -y --no-install-recommends \ libgomp1 \ curl \ && rm -rf /var/lib/apt/lists/* # Copy installed Python packages from builder COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages COPY --from=builder /usr/local/bin /usr/local/bin # Create non-root user with UID 1000 (Mandatory for Hugging Face Spaces) RUN useradd -m -u 1000 user # Configure environment for Hugging Face Spaces & Render ENV HOME=/home/user \ PATH=/home/user/.local/bin:$PATH \ HF_HOME=/home/user/.cache/huggingface \ PYTHONUNBUFFERED=1 \ PYTHONPATH=/app:/app/cpp_engine \ SERVER_HOST=0.0.0.0 \ SERVER_PORT=7860 \ USE_LOCAL_SIMULATOR=true # Prepare home and app directories with proper ownership for UID 1000 WORKDIR /app RUN mkdir -p /home/user/.cache/huggingface /app && \ chown -R user:user /home/user /app # Switch to non-root user (Hugging Face Spaces requirement) USER user # Pre-download all-MiniLM-L6-v2 model so it is baked into /home/user/.cache/huggingface RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2', device='cpu')" # Copy compiled SIMD extension with correct ownership COPY --chown=user:user --from=builder /build/cpp_engine/simd_engine*.so /app/ COPY --chown=user:user --from=builder /build/cpp_engine/simd_engine*.so /app/cpp_engine/ # Copy application source code & data COPY --chown=user:user app/ /app/app/ COPY --chown=user:user data/ /app/data/ COPY --chown=user:user benchmarks/ /app/benchmarks/ COPY --chown=user:user tests/ /app/tests/ EXPOSE 7860 HEALTHCHECK --interval=20s --timeout=5s --start-period=30s --retries=3 \ CMD curl -f http://localhost:${PORT:-7860}/v1/health || exit 1 CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860} --workers 1"]