build: add dependency caching for bundle builds
Cache pip/npm dependency downloads via BuildKit cache mounts and skip the postgres pull when the image is already present locally, so a repeat ./build.sh bundle run does not download dependencies twice.
This commit is contained in:
24
build.sh
24
build.sh
@@ -41,6 +41,8 @@ set -euo pipefail
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
cd "$SCRIPT_DIR"
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
export DOCKER_BUILDKIT=1
|
||||||
|
|
||||||
BACKEND_ENV_FILE="$SCRIPT_DIR/backend/.env"
|
BACKEND_ENV_FILE="$SCRIPT_DIR/backend/.env"
|
||||||
DIST_ROOT="$SCRIPT_DIR/dist/docker"
|
DIST_ROOT="$SCRIPT_DIR/dist/docker"
|
||||||
|
|
||||||
@@ -158,6 +160,17 @@ get_repo_digest() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Pull an image only if it is not already present locally.
|
||||||
|
ensure_image_present() {
|
||||||
|
local source="$1"
|
||||||
|
if docker image inspect "$source" >/dev/null 2>&1; then
|
||||||
|
echo "[bundle] Image ${source} already present, skipping pull"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
docker pull "$source"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
resolve_app_version() {
|
resolve_app_version() {
|
||||||
local tag="$1"
|
local tag="$1"
|
||||||
local git_commit
|
local git_commit
|
||||||
@@ -719,8 +732,8 @@ bundle_release() {
|
|||||||
build_agent "${tag}"
|
build_agent "${tag}"
|
||||||
|
|
||||||
# Pull and tag postgres image
|
# Pull and tag postgres image
|
||||||
echo "[bundle] Pulling postgres image ${postgres_source}..."
|
echo "[bundle] Ensuring postgres image ${postgres_source}..."
|
||||||
docker pull "${postgres_source}"
|
ensure_image_present "${postgres_source}"
|
||||||
docker tag "${postgres_source}" "${postgres_tag}"
|
docker tag "${postgres_source}" "${postgres_tag}"
|
||||||
|
|
||||||
# Release gate: fresh PostgreSQL migration + backend boot + restart must pass.
|
# Release gate: fresh PostgreSQL migration + backend boot + restart must pass.
|
||||||
@@ -905,8 +918,8 @@ bundle_embeddings() {
|
|||||||
build_agent_embeddings "${tag}${suffix}"
|
build_agent_embeddings "${tag}${suffix}"
|
||||||
|
|
||||||
# Pull and tag postgres image
|
# Pull and tag postgres image
|
||||||
echo "[bundle:embeddings] Pulling postgres image ${postgres_source}..."
|
echo "[bundle:embeddings] Ensuring postgres image ${postgres_source}..."
|
||||||
docker pull "${postgres_source}"
|
ensure_image_present "${postgres_source}"
|
||||||
docker tag "${postgres_source}" "${postgres_tag}"
|
docker tag "${postgres_source}" "${postgres_tag}"
|
||||||
|
|
||||||
# Release gate: fresh PostgreSQL migration + backend boot + restart must pass.
|
# Release gate: fresh PostgreSQL migration + backend boot + restart must pass.
|
||||||
@@ -1023,6 +1036,9 @@ Notes:
|
|||||||
- Bundle commands (bundle, bundle:embeddings) now include postgres:16-alpine
|
- Bundle commands (bundle, bundle:embeddings) now include postgres:16-alpine
|
||||||
as superset-tools-postgres:<tag> — loaded together with other images
|
as superset-tools-postgres:<tag> — loaded together with other images
|
||||||
via 'xz -dc ... | docker load'. No external PostgreSQL required.
|
via 'xz -dc ... | docker load'. No external PostgreSQL required.
|
||||||
|
- pip/npm dependency downloads are cached via BuildKit cache mounts and the
|
||||||
|
postgres pull is skipped when the image is already present locally.
|
||||||
|
Clear the dependency cache with: docker buildx prune
|
||||||
HELP
|
HELP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,14 @@ RUN pip install --no-cache-dir -e /app/shared/
|
|||||||
|
|
||||||
# Install agent requirements
|
# Install agent requirements
|
||||||
COPY agent/requirements.txt /app/agent/requirements.txt
|
COPY agent/requirements.txt /app/agent/requirements.txt
|
||||||
RUN pip install --no-cache-dir -r /app/agent/requirements.txt
|
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||||
|
pip install -r /app/agent/requirements.txt
|
||||||
|
|
||||||
# Optional: semantic embedding routing
|
# Optional: semantic embedding routing
|
||||||
COPY agent/requirements-embeddings.txt /app/agent/requirements-embeddings.txt
|
COPY agent/requirements-embeddings.txt /app/agent/requirements-embeddings.txt
|
||||||
RUN if [ "$WITH_EMBEDDINGS" = "true" ]; then \
|
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||||
pip install --no-cache-dir -r /app/agent/requirements-embeddings.txt; \
|
if [ "$WITH_EMBEDDINGS" = "true" ]; then \
|
||||||
|
pip install -r /app/agent/requirements-embeddings.txt; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Agent source code
|
# Agent source code
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ WORKDIR /app/frontend
|
|||||||
|
|
||||||
# Install deps (layer cache when package.json unchanged)
|
# Install deps (layer cache when package.json unchanged)
|
||||||
COPY frontend/package.json frontend/package-lock.json* ./
|
COPY frontend/package.json frontend/package-lock.json* ./
|
||||||
RUN npm ci --prefer-offline --no-audit --no-fund --legacy-peer-deps
|
RUN --mount=type=cache,target=/root/.npm \
|
||||||
|
npm ci --prefer-offline --no-audit --no-fund --legacy-peer-deps
|
||||||
|
|
||||||
# Build frontend
|
# Build frontend
|
||||||
COPY frontend/ ./
|
COPY frontend/ ./
|
||||||
@@ -43,7 +44,8 @@ RUN apt-get update \
|
|||||||
|
|
||||||
# Python deps (NO playwright — saves ~350MB)
|
# Python deps (NO playwright — saves ~350MB)
|
||||||
COPY backend/requirements-backend.txt /app/backend/requirements-backend.txt
|
COPY backend/requirements-backend.txt /app/backend/requirements-backend.txt
|
||||||
RUN pip install --no-cache-dir -r /app/backend/requirements-backend.txt
|
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||||
|
pip install -r /app/backend/requirements-backend.txt
|
||||||
|
|
||||||
# Backend source
|
# Backend source
|
||||||
COPY backend/ /app/backend/
|
COPY backend/ /app/backend/
|
||||||
|
|||||||
@@ -25,14 +25,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
|
|
||||||
# Python зависимости — backend runtime
|
# Python зависимости — backend runtime
|
||||||
COPY backend/requirements-backend.txt /app/backend/requirements-backend.txt
|
COPY backend/requirements-backend.txt /app/backend/requirements-backend.txt
|
||||||
RUN pip install --no-cache-dir -r /app/backend/requirements-backend.txt
|
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||||
|
pip install -r /app/backend/requirements-backend.txt
|
||||||
|
|
||||||
# Install shared package (LLM health, SSL, cot_logger)
|
# Install shared package (LLM health, SSL, cot_logger)
|
||||||
COPY shared/ /app/shared/
|
COPY shared/ /app/shared/
|
||||||
RUN pip install --no-cache-dir -e /app/shared/
|
RUN pip install --no-cache-dir -e /app/shared/
|
||||||
|
|
||||||
# Install shared LLM deps (openai, httpx for _llm_health)
|
# Install shared LLM deps (openai, httpx for _llm_health)
|
||||||
RUN pip install --no-cache-dir "openai>=1.0.0" "httpx>=0.28.1"
|
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||||
|
pip install "openai>=1.0.0" "httpx>=0.28.1"
|
||||||
|
|
||||||
# Browser binaries are required only by screenshot-capable deployments. API-only E2E
|
# Browser binaries are required only by screenshot-capable deployments. API-only E2E
|
||||||
# stacks can opt out through INSTALL_PLAYWRIGHT_BROWSERS=0 to reduce image build pressure.
|
# stacks can opt out through INSTALL_PLAYWRIGHT_BROWSERS=0 to reduce image build pressure.
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ ENV APP_VERSION=${APP_VERSION}
|
|||||||
WORKDIR /app/frontend
|
WORKDIR /app/frontend
|
||||||
|
|
||||||
COPY frontend/package*.json ./
|
COPY frontend/package*.json ./
|
||||||
RUN npm ci --legacy-peer-deps
|
RUN --mount=type=cache,target=/root/.npm \
|
||||||
|
npm ci --legacy-peer-deps
|
||||||
|
|
||||||
COPY frontend/ ./
|
COPY frontend/ ./
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|||||||
Reference in New Issue
Block a user