# Start from a minimal Python image. Slim reduces size while keeping Python. FROM python:3.12-slim # Make Python output unbuffered (better real-time logs) ENV PYTHONUNBUFFERED=1 # Create a non-root user to run the app (security best-practice). RUN useradd --create-home --shell /bin/bash app # Set working directory for subsequent commands and the container runtime. WORKDIR /app # Install system dependencies needed to build Python packages and tooling. # --no-install-recommends keeps the image smaller by avoiding extra packages. RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ g++ \ curl \ && rm -rf /var/lib/apt/lists/* # Upgrade pip and related build tools, and install uv (project's runtime manager). # --no-cache-dir avoids leaving pip cache in the image. RUN python -m pip install --upgrade pip setuptools wheel && \ pip install --no-cache-dir uv # Copy project files into the image. COPY . . # Ensure the non-root user owns the app directory so it can run/install files there. RUN chown -R app:app /app # Switch to the non-root user for better security for subsequent steps. USER app # Set uv cache dir to somewhere writable by the app user. This avoids permission errors # when uv manages its own cache during `uv sync` or runtime. ENV UV_CACHE_DIR=/app/.uv-cache # Install application dependencies using uv. Running this as the non-root `app` user # keeps the image consistent with runtime permissions. `--frozen` ensures deterministic installs. RUN uv sync --frozen # Expose the port Gradio uses (default in the project). This is informational and # useful for container orchestration and documentation. EXPOSE 7860 # Set Gradio environment variables so the app binds to all interfaces in containers. ENV GRADIO_SERVER_NAME="0.0.0.0" ENV GRADIO_SERVER_PORT=7860 # Default command: run the Gradio app via uv. Using uv run keeps the environment consistent # with development workflows that rely on uv. CMD ["uv", "run", "python", "src/sales_assistant/ui_dashboard/gradio_app.py"]