Skip to content

Commit

Permalink
Use docker cache mounts for apt, pip and cargo
Browse files Browse the repository at this point in the history
The cache mounts are cached using standard github actions cache
when building in the CI pipeline.

Note that the build stage no longer contains the whole source tree,
these are instead mounted into the build container when building to
avoid invalidating cached build container layers.
  • Loading branch information
mjpieters committed Jan 31, 2025
1 parent d517b1c commit 6cc484d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 11 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:

# Login to DockerHub first, to avoid rate-limiting
- uses: docker/login-action@v3
# PRs from forks don't have access to secrets, disable this step in that case.
if: ${{ github.event.pull_request.head.repo.full_name == 'astral-sh/uv' }}
with:
username: astralshbot
password: ${{ secrets.DOCKERHUB_TOKEN_RO }}
Expand Down Expand Up @@ -79,6 +81,48 @@ jobs:
platform=${{ matrix.platform }}
echo "PLATFORM_TUPLE=${platform//\//-}" >> $GITHUB_ENV
- name: Docker apt & pip caches
uses: actions/cache@v4
id: docker-caches
with:
path: |
var-cache-apt
var-lib-apt
root-cache-pip
key: docker-caches-${{ matrix.platform }}-${{ hashFiles('Dockerfile') }}

- name: Docker Cargo caches
uses: actions/cache@v4
id: docker-cargo-caches
with:
path: |
root-target
usr-local-cargo-git-db
usr-local-cargo-registry
key: docker-cargo-caches-${{ matrix.platform }}-${{ hashFiles('Dockerfile', 'crates/**', 'Cargo.toml', 'Cargo.lock') }}

- name: Inject apt & pip caches into docker
uses: reproducible-containers/buildkit-cache-dance@v3
with:
cache-map: |
{
"var-cache-apt": "/var/cache/apt",
"var-lib-apt": "/var/lib/apt",
"root-cache-pip": "/root/.cache/pip"
}
skip-extraction: ${{ steps.docker-caches.outputs.cache-hit }}

- name: Inject Cargo caches into docker
uses: reproducible-containers/buildkit-cache-dance@v3
with:
cache-map: |
{
"root-target": "/root/target",
"usr-local-cargo-git-db": "/usr/local/cargo/git/db",
"usr-local-cargo-registry": "/usr/local/cargo/registry/"
}
skip-extraction: ${{ steps.docker-cargo-caches.outputs.cache-hit }}

# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
- name: Build and push by digest
id: build
Expand Down
36 changes: 25 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ FROM --platform=$BUILDPLATFORM ubuntu AS build
ENV HOME="/root"
WORKDIR $HOME

RUN apt update \
RUN \
--mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
# remove the default docker-specific apt config that auto-deletes /var/apt/cache archives
rm -f /etc/apt/apt.conf.d/docker-clean && \
# and configure apt-get to keep downloaded archives in the cache
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
apt update \
&& apt install -y --no-install-recommends \
build-essential \
curl \
python3-venv \
cmake \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*
cmake

# Setup zig as cross compiling linker
RUN python3 -m venv $HOME/.venv
RUN .venv/bin/pip install cargo-zigbuild
RUN \
--mount=type=cache,target=/root/.cache/pip \
.venv/bin/pip install cargo-zigbuild
ENV PATH="$HOME/.venv/bin:$PATH"

# Install rust
Expand All @@ -32,14 +39,21 @@ ENV PATH="$HOME/.cargo/bin:$PATH"
RUN rustup target add $(cat rust_target.txt)

# Build
COPY crates crates
COPY ./Cargo.toml Cargo.toml
COPY ./Cargo.lock Cargo.lock
RUN case "${TARGETPLATFORM}" in \
RUN \
# bind mounts to access Cargo config, lock, and sources, without having to
# copy them into the build layer and so bloat the docker build cache
--mount=type=bind,source=crates,target=crates \
--mount=type=bind,source=Cargo.toml,target=Cargo.toml \
--mount=type=bind,source=Cargo.lock,target=Cargo.lock \
# Cache mounts to speed up builds
--mount=type=cache,target=/root/target/ \
--mount=type=cache,target=/usr/local/cargo/git/db \
--mount=type=cache,target=/usr/local/cargo/registry/ \
case "${TARGETPLATFORM}" in \
"linux/arm64") export JEMALLOC_SYS_WITH_LG_PAGE=16;; \
esac && \
cargo zigbuild --bin uv --bin uvx --target $(cat rust_target.txt) --release
RUN cp target/$(cat rust_target.txt)/release/uv /uv \
cargo zigbuild --bin uv --bin uvx --target $(cat rust_target.txt) --release \
&& cp target/$(cat rust_target.txt)/release/uv /uv \
&& cp target/$(cat rust_target.txt)/release/uvx /uvx
# TODO(konsti): Optimize binary size, with a version that also works when cross compiling
# RUN strip --strip-all /uv
Expand Down

0 comments on commit 6cc484d

Please sign in to comment.