@@ -10,19 +10,13 @@ FROM ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-bookworm-slim AS base
1010# the application crashes without emitting any logs due to buffering.
1111ENV PYTHONUNBUFFERED=1
1212
13- # Create a non-privileged user that the app will run under.
14- # See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
15- ARG UID=10001
16- RUN adduser \
17- --disabled-password \
18- --gecos "" \
19- --home "/app" \
20- --shell "/sbin/nologin" \
21- --uid "${UID}" \
22- appuser
13+ # --- Build stage ---
14+ # Install dependencies, build native extensions, and prepare the application
15+ FROM base AS build
2316
2417# Install build dependencies required for Python packages with native extensions
2518# gcc: C compiler needed for building Python packages with C extensions
19+ # g++: C++ compiler needed for building Python packages with C++ extensions
2620# python3-dev: Python development headers needed for compilation
2721# We clean up the apt cache after installation to keep the image size down
2822RUN apt-get update && apt-get install -y \
@@ -50,20 +44,35 @@ RUN uv sync --locked
5044# (Excludes files specified in .dockerignore)
5145COPY . .
5246
53- # Change ownership of all app files to the non-privileged user
54- # This ensures the application can read/write files as needed
55- RUN chown -R appuser:appuser /app
47+ # Pre-download any ML models or files the agent needs
48+ # This ensures the container is ready to run immediately without downloading
49+ # dependencies at runtime, which improves startup time and reliability
50+ RUN uv run "src/agent.py" download-files
51+
52+ # --- Production stage ---
53+ # Build tools (gcc, g++, python3-dev) are not included in the final image
54+ FROM base
55+
56+ # Create a non-privileged user that the app will run under.
57+ # See https://docs.docker.com/build/building/best-practices/#user
58+ ARG UID=10001
59+ RUN adduser \
60+ --disabled-password \
61+ --gecos "" \
62+ --home "/app" \
63+ --shell "/sbin/nologin" \
64+ --uid "${UID}" \
65+ appuser
66+
67+ # Copy the application and virtual environment with correct ownership in a single layer
68+ # This avoids expensive recursive chown and excludes build tools from the final image
69+ COPY --from=build --chown=appuser:appuser /app /app
5670
5771# Switch to the non-privileged user for all subsequent operations
5872# This improves security by not running as root
5973USER appuser
6074
61- # Pre-download any ML models or files the agent needs
62- # This ensures the container is ready to run immediately without downloading
63- # dependencies at runtime, which improves startup time and reliability
64- RUN uv run src/agent.py download-files
65-
66- # Run the application using UV
75+ # Run the AgentServer using UV
6776# UV will activate the virtual environment and run the agent.
68- # The "start" command tells the worker to connect to LiveKit and begin waiting for jobs.
77+ # The "start" command tells the AgentServer to connect to LiveKit and begin waiting for jobs.
6978CMD ["uv" , "run" , "src/agent.py" , "start" ]
0 commit comments