From 7b811c0516baffdf34e67c57fdabca102e22f0ea Mon Sep 17 00:00:00 2001 From: Devon Peticolas Date: Tue, 3 Mar 2026 14:00:00 -0500 Subject: [PATCH] Use uv sync --locked in Dockerfile templates per official uv Docker guidance Replace `uv pip install --system` with `uv sync --locked` in all 7 Dockerfile-uv.j2 templates. This uses the uv.lock file for reproducible builds, adds two-stage dependency installation for layer caching, BuildKit cache mounts, UV_COMPILE_BYTECODE for faster startup, and virtualenv PATH. Also remove uv.lock from existing .gitignore files that were blocking it. --- .gitignore | 2 -- examples/demos/procurement_agent/.gitignore | 1 - .../default-langgraph/Dockerfile-uv.j2 | 23 ++++++++++------- .../cli/templates/default/Dockerfile-uv.j2 | 23 ++++++++++------- .../templates/sync-langgraph/Dockerfile-uv.j2 | 23 ++++++++++------- .../sync-openai-agents/Dockerfile-uv.j2 | 23 ++++++++++------- .../lib/cli/templates/sync/Dockerfile-uv.j2 | 23 ++++++++++------- .../temporal-openai-agents/Dockerfile-uv.j2 | 25 ++++++++++++------- .../cli/templates/temporal/Dockerfile-uv.j2 | 25 ++++++++++++------- 9 files changed, 102 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index 3666be24a..6398505af 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,5 @@ Brewfile.lock.json .DS_Store -examples/**/uv.lock - # Claude workspace directories .claude-workspace/ \ No newline at end of file diff --git a/examples/demos/procurement_agent/.gitignore b/examples/demos/procurement_agent/.gitignore index 127b65a2c..92316bc3d 100644 --- a/examples/demos/procurement_agent/.gitignore +++ b/examples/demos/procurement_agent/.gitignore @@ -60,4 +60,3 @@ htmlcov/ # UV .venv/ -uv.lock diff --git a/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 index 2ac5be7d2..582434ac9 100644 --- a/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 @@ -20,22 +20,27 @@ RUN apt-get update && apt-get install -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/** -RUN uv pip install --system --upgrade pip setuptools wheel - +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_HTTP_TIMEOUT=1000 -# Copy just the pyproject.toml file to optimize caching -COPY {{ project_path_from_build_root }}/pyproject.toml /app/{{ project_path_from_build_root }}/pyproject.toml - WORKDIR /app/{{ project_path_from_build_root }} -# Install the required Python packages using uv -RUN uv pip install --system . +# Copy dependency files for layer caching +COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ + +# Install dependencies (without project itself, for layer caching) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-install-project --no-dev # Copy the project code -COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project +COPY {{ project_path_from_build_root }}/project ./project + +# Install the project +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev -# Set environment variables +ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" ENV PYTHONPATH=/app # Run the agent using uvicorn diff --git a/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 index 2ac5be7d2..582434ac9 100644 --- a/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 @@ -20,22 +20,27 @@ RUN apt-get update && apt-get install -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/** -RUN uv pip install --system --upgrade pip setuptools wheel - +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_HTTP_TIMEOUT=1000 -# Copy just the pyproject.toml file to optimize caching -COPY {{ project_path_from_build_root }}/pyproject.toml /app/{{ project_path_from_build_root }}/pyproject.toml - WORKDIR /app/{{ project_path_from_build_root }} -# Install the required Python packages using uv -RUN uv pip install --system . +# Copy dependency files for layer caching +COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ + +# Install dependencies (without project itself, for layer caching) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-install-project --no-dev # Copy the project code -COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project +COPY {{ project_path_from_build_root }}/project ./project + +# Install the project +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev -# Set environment variables +ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" ENV PYTHONPATH=/app # Run the agent using uvicorn diff --git a/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 index 2ac5be7d2..582434ac9 100644 --- a/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 @@ -20,22 +20,27 @@ RUN apt-get update && apt-get install -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/** -RUN uv pip install --system --upgrade pip setuptools wheel - +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_HTTP_TIMEOUT=1000 -# Copy just the pyproject.toml file to optimize caching -COPY {{ project_path_from_build_root }}/pyproject.toml /app/{{ project_path_from_build_root }}/pyproject.toml - WORKDIR /app/{{ project_path_from_build_root }} -# Install the required Python packages using uv -RUN uv pip install --system . +# Copy dependency files for layer caching +COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ + +# Install dependencies (without project itself, for layer caching) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-install-project --no-dev # Copy the project code -COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project +COPY {{ project_path_from_build_root }}/project ./project + +# Install the project +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev -# Set environment variables +ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" ENV PYTHONPATH=/app # Run the agent using uvicorn diff --git a/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 index 2ac5be7d2..582434ac9 100644 --- a/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 @@ -20,22 +20,27 @@ RUN apt-get update && apt-get install -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/** -RUN uv pip install --system --upgrade pip setuptools wheel - +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_HTTP_TIMEOUT=1000 -# Copy just the pyproject.toml file to optimize caching -COPY {{ project_path_from_build_root }}/pyproject.toml /app/{{ project_path_from_build_root }}/pyproject.toml - WORKDIR /app/{{ project_path_from_build_root }} -# Install the required Python packages using uv -RUN uv pip install --system . +# Copy dependency files for layer caching +COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ + +# Install dependencies (without project itself, for layer caching) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-install-project --no-dev # Copy the project code -COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project +COPY {{ project_path_from_build_root }}/project ./project + +# Install the project +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev -# Set environment variables +ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" ENV PYTHONPATH=/app # Run the agent using uvicorn diff --git a/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 index 2ac5be7d2..582434ac9 100644 --- a/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 @@ -20,22 +20,27 @@ RUN apt-get update && apt-get install -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/** -RUN uv pip install --system --upgrade pip setuptools wheel - +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_HTTP_TIMEOUT=1000 -# Copy just the pyproject.toml file to optimize caching -COPY {{ project_path_from_build_root }}/pyproject.toml /app/{{ project_path_from_build_root }}/pyproject.toml - WORKDIR /app/{{ project_path_from_build_root }} -# Install the required Python packages using uv -RUN uv pip install --system . +# Copy dependency files for layer caching +COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ + +# Install dependencies (without project itself, for layer caching) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-install-project --no-dev # Copy the project code -COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project +COPY {{ project_path_from_build_root }}/project ./project + +# Install the project +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev -# Set environment variables +ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" ENV PYTHONPATH=/app # Run the agent using uvicorn diff --git a/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 index 81dd9c5b6..625592d31 100644 --- a/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 @@ -26,23 +26,30 @@ RUN curl -L https://github.com/temporalio/tctl/releases/download/v1.18.1/tctl_1. chmod +x /usr/local/bin/tctl && \ rm /tmp/tctl.tar.gz -RUN uv pip install --system --upgrade pip setuptools wheel - +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_HTTP_TIMEOUT=1000 -# Copy just the pyproject.toml file to optimize caching -COPY {{ project_path_from_build_root }}/pyproject.toml /app/{{ project_path_from_build_root }}/pyproject.toml - WORKDIR /app/{{ project_path_from_build_root }} -# Install the required Python packages using uv -RUN uv pip install --system . +# Copy dependency files for layer caching +COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ + +# Install dependencies (without project itself, for layer caching) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-install-project --no-dev # Copy the project code -COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project +COPY {{ project_path_from_build_root }}/project ./project + +# Install the project +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev + +ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" # Run the ACP server using uvicorn CMD ["uvicorn", "project.acp:acp", "--host", "0.0.0.0", "--port", "8000"] # When we deploy the worker, we will replace the CMD with the following -# CMD ["python", "-m", "run_worker"] \ No newline at end of file +# CMD ["python", "-m", "run_worker"] \ No newline at end of file diff --git a/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 index 81dd9c5b6..625592d31 100644 --- a/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 @@ -26,23 +26,30 @@ RUN curl -L https://github.com/temporalio/tctl/releases/download/v1.18.1/tctl_1. chmod +x /usr/local/bin/tctl && \ rm /tmp/tctl.tar.gz -RUN uv pip install --system --upgrade pip setuptools wheel - +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy ENV UV_HTTP_TIMEOUT=1000 -# Copy just the pyproject.toml file to optimize caching -COPY {{ project_path_from_build_root }}/pyproject.toml /app/{{ project_path_from_build_root }}/pyproject.toml - WORKDIR /app/{{ project_path_from_build_root }} -# Install the required Python packages using uv -RUN uv pip install --system . +# Copy dependency files for layer caching +COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ + +# Install dependencies (without project itself, for layer caching) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-install-project --no-dev # Copy the project code -COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project +COPY {{ project_path_from_build_root }}/project ./project + +# Install the project +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev + +ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" # Run the ACP server using uvicorn CMD ["uvicorn", "project.acp:acp", "--host", "0.0.0.0", "--port", "8000"] # When we deploy the worker, we will replace the CMD with the following -# CMD ["python", "-m", "run_worker"] \ No newline at end of file +# CMD ["python", "-m", "run_worker"] \ No newline at end of file