# tau-rag production Dockerfile (hardened) # Multi-stage: builder → runtime. Runs as non-root with HEALTHCHECK. # Build: docker build -f Dockerfile.prod -t tau-rag:prod . # ============================================================================= # Stage 1: builder — compiles wheels, keeps toolchains out of final image # ============================================================================= FROM python:3.11-slim AS builder ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 WORKDIR /build # System build deps (BLAS for numpy, gcc for any C extensions) RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ gfortran \ libopenblas-dev \ liblapack-dev \ curl \ && rm -rf /var/lib/apt/lists/* # Create the venv we'll copy into runtime RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" # Install pinned production requirements COPY requirements.txt /build/requirements.txt RUN pip install --upgrade pip setuptools wheel \ && pip install -r /build/requirements.txt # ============================================================================= # Stage 2: runtime — slim, non-root, with HEALTHCHECK # ============================================================================= FROM python:3.11-slim AS runtime ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PYTHONPATH=/app \ PATH="/opt/venv/bin:$PATH" \ TAU_RAG_HOST=0.0.0.0 \ TAU_RAG_PORT=8000 \ TAU_RAG_WORKERS=4 \ TAU_RAG_LOG_LEVEL=INFO \ TAU_RAG_PRESET=hebrew_legal_prod \ TAU_RAG_RUNTIME_DIR=/app/runtime \ HF_HOME=/home/taurag/.cache/huggingface # Runtime system deps (NO compiler) RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ libopenblas0 \ tini \ && rm -rf /var/lib/apt/lists/* # Non-root user (UID 10001 for OpenShift-style namespaces) RUN groupadd --system --gid 10001 taurag \ && useradd --system --uid 10001 --gid taurag --create-home --shell /sbin/nologin taurag WORKDIR /app # Copy pre-built venv from builder COPY --from=builder /opt/venv /opt/venv # Copy app code (after deps so code changes don't invalidate deps layer) COPY --chown=taurag:taurag . /app/tau_rag # Make entrypoint scripts executable RUN chmod +x /app/tau_rag/scripts/entrypoint.sh /app/tau_rag/scripts/healthcheck.sh \ && mkdir -p /app/runtime /home/taurag/.cache/huggingface \ && chown -R taurag:taurag /app /home/taurag USER taurag EXPOSE 8000 # Container-native health probe (also used by k8s via command) HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ CMD /app/tau_rag/scripts/healthcheck.sh || exit 1 # tini as PID 1: reaps zombies, forwards signals cleanly → graceful shutdown ENTRYPOINT ["/usr/bin/tini", "--", "/app/tau_rag/scripts/entrypoint.sh"] CMD ["serve"]