# ─── Stage 1: Builder ──────────────────────────────────────────────────────── FROM python:3.13-slim AS builder # Native build tools required by packages with C extensions RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ g++ \ libffi-dev \ libssl-dev \ make \ && rm -rf /var/lib/apt/lists/* WORKDIR /build COPY requirements.txt . # Install all dependencies into an isolated prefix so the runtime stage # can copy them without pulling in the build toolchain. RUN pip install --no-cache-dir --prefix=/install -r requirements.txt # ─── Stage 2: Runtime ──────────────────────────────────────────────────────── FROM python:3.13-slim AS runtime # Copy compiled packages from the builder — no build tools in the final image COPY --from=builder /install /usr/local WORKDIR /app # Entrypoint: materialises GOOGLE_APPLICATION_CREDENTIALS_JSON → temp file COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh # Application source COPY app.py chain.py db.py ./ COPY models/ models/ COPY templates/ templates/ COPY static/ static/ # Prompt templates read at runtime by chain.py COPY prompt.md question_rewrite_prompt.md ./ # Initial database (mount a named volume here for persistence across restarts) COPY example.db . # PORT is read by the __main__ entry-point and by the CMD below. # Override at runtime with: docker run -e PORT=9090 ... ENV PORT=8080 EXPOSE 8080 ENTRYPOINT ["/entrypoint.sh"] # Production command: `fastapi run` wraps uvicorn without --reload. CMD ["sh", "-c", "exec fastapi run app.py --host 0.0.0.0 --port ${PORT}"]