# Stage 1: Build stage with uv FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder WORKDIR /app # Enable bytecode compilation for faster startup ENV UV_COMPILE_BYTECODE=1 # Copy from the cache instead of linking (required for multi-stage) ENV UV_LINK_MODE=copy # Install dependencies first (cached layer) COPY pyproject.toml uv.lock ./ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --frozen --no-install-project --no-dev # Copy application code and install project COPY app.py ./ COPY pages/ ./pages/ COPY config.py ./ COPY .streamlit/ ./.streamlit/ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --frozen --no-dev # Stage 2: Runtime stage (minimal image) FROM python:3.13-slim-bookworm AS runtime WORKDIR /app # Install LaTeX and build dependencies for tueplots/matplotlib RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ texlive-latex-base \ texlive-latex-extra \ texlive-fonts-recommended \ texlive-fonts-extra \ cm-super \ dvipng \ ghostscript \ lmodern \ fontconfig \ && rm -rf /var/lib/apt/lists/* \ && fc-cache -f # Copy the resolved virtualenv from the builder stage. COPY --from=builder /app/.venv /app/.venv # Copy application code COPY app.py ./ COPY pages/ ./pages/ COPY config.py ./ COPY .streamlit/ ./.streamlit/ # Create non-root user for security RUN useradd --create-home --shell /bin/bash appuser USER appuser # Set environment variables ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 ENV PATH="/app/.venv/bin:$PATH" ENV DEMO_DATA_DIR=/data # Streamlit configuration ENV STREAMLIT_SERVER_PORT=7860 ENV STREAMLIT_SERVER_ADDRESS=0.0.0.0 ENV STREAMLIT_SERVER_HEADLESS=true ENV STREAMLIT_BROWSER_GATHER_USAGE_STATS=false EXPOSE 7860 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/_stcore/health')" # Run streamlit CMD ["streamlit", "run", "app.py"]