perf: switch to uv for faster dependency installation
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

- Replace pip with uv in Dockerfile.service builder stage (~5-10x faster)
- Replace pip with uv in CI test step
- Separate pyproject.toml copy from source copy in Dockerfile for better
  Docker layer caching (deps only reinstalled when pyproject.toml changes)
- Add cache_from for buildx to reuse layers from previous builds
- Remove pip cache workaround from test step (not persisted in K8s)
This commit is contained in:
Viktor Barzin 2026-02-25 22:55:58 +00:00
parent 5955a5a86d
commit 0a017f52cb
No known key found for this signature in database
GPG key ID: 0EB088298288D958
2 changed files with 23 additions and 20 deletions

View file

@ -11,23 +11,13 @@ clone:
steps: steps:
- name: test - name: test
image: python:3.12-slim image: docker.io/library/python:3.12-slim
commands: commands:
- | - pip install uv
if [ -d /woodpecker/pip-cache ]; then
echo "Restoring pip cache..."
cp -r /woodpecker/pip-cache .pip-cache
fi
- python -m venv .venv
- >- - >-
.venv/bin/pip install --quiet --upgrade pip uv pip install --system --quiet
- >-
.venv/bin/pip install --quiet --cache-dir .pip-cache
".[api,news,sentiment,trading,backtester,dev]" ".[api,news,sentiment,trading,backtester,dev]"
- .venv/bin/pytest tests/ -v --tb=short -m "not integration" - python -m pytest tests/ -v --tb=short -m "not integration"
- |
echo "Saving pip cache..."
cp -r .pip-cache /woodpecker/pip-cache 2>/dev/null || true
- name: build-service-image - name: build-service-image
image: woodpeckerci/plugin-docker-buildx image: woodpeckerci/plugin-docker-buildx
@ -42,6 +32,7 @@ steps:
context: . context: .
build_args: build_args:
- SERVICE_MODULE=api_gateway - SERVICE_MODULE=api_gateway
cache_from: viktorbarzin/trading-bot-service:latest
tags: tags:
- "${CI_PIPELINE_NUMBER}" - "${CI_PIPELINE_NUMBER}"
- latest - latest
@ -59,12 +50,13 @@ steps:
context: . context: .
build_args: build_args:
- NGINX_CONF=docker/nginx-k8s.conf - NGINX_CONF=docker/nginx-k8s.conf
cache_from: viktorbarzin/trading-bot-dashboard:latest
tags: tags:
- "${CI_PIPELINE_NUMBER}" - "${CI_PIPELINE_NUMBER}"
- latest - latest
- name: update-deployment - name: update-deployment
image: alpine image: docker.io/library/alpine
depends_on: depends_on:
- build-service-image - build-service-image
- build-dashboard-image - build-dashboard-image
@ -118,7 +110,7 @@ steps:
}" | jq '{name: .metadata.name, generation: .metadata.generation}' }" | jq '{name: .metadata.name, generation: .metadata.generation}'
- name: verify-deploy - name: verify-deploy
image: alpine image: docker.io/library/alpine
depends_on: depends_on:
- update-deployment - update-deployment
commands: commands:

View file

@ -1,6 +1,5 @@
# Multi-stage Dockerfile for all Python microservices. # Multi-stage Dockerfile for all Python microservices.
# Build args: # Build args:
# EXTRAS — pip optional-dependency groups (e.g. "news", "sentiment,trading")
# SERVICE_MODULE — Python module name under services/ (e.g. "news_fetcher") # SERVICE_MODULE — Python module name under services/ (e.g. "news_fetcher")
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -10,16 +9,28 @@ FROM python:3.12-slim AS builder
WORKDIR /app WORKDIR /app
# Copy project metadata and source so pip can resolve the local package # Install uv for fast dependency resolution
RUN pip install uv
# Copy ONLY dependency metadata first — this layer is cached until
# pyproject.toml changes, so dependency install is skipped on pure code changes.
COPY pyproject.toml . COPY pyproject.toml .
# Create minimal package stubs so uv can resolve the local editable install
# without copying all source (which would bust the cache on every commit).
RUN mkdir -p shared services backtester && \
uv pip install --system --no-cache-dir ".[api,news,sentiment,trading,backtester]" && \
uv pip install --system --no-cache-dir curl_cffi 2>/dev/null || true
# NOW copy the actual source code (changes here don't re-trigger dep install)
COPY shared/ shared/ COPY shared/ shared/
COPY services/ services/ COPY services/ services/
COPY backtester/ backtester/ COPY backtester/ backtester/
COPY alembic/ alembic/ COPY alembic/ alembic/
COPY alembic.ini . COPY alembic.ini .
# Install all service dependencies (hardcoded to avoid build-arg comma parsing issues) # Re-install in-place so the package metadata points to actual source
RUN pip install --no-cache-dir ".[api,news,sentiment,trading,backtester]" && pip install --no-cache-dir curl_cffi 2>/dev/null || true RUN uv pip install --system --no-cache-dir --no-deps -e .
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Stage 2: slim runtime image # Stage 2: slim runtime image