Skip to content

Commit 79d5163

Browse files
committed
Use docker cache mounts for apt, pip and cargo
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.
1 parent d517b1c commit 79d5163

File tree

2 files changed

+69
-11
lines changed

2 files changed

+69
-11
lines changed

.github/workflows/build-docker.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ jobs:
3939

4040
# Login to DockerHub first, to avoid rate-limiting
4141
- uses: docker/login-action@v3
42+
# PRs from forks don't have access to secrets, disable this step in that case.
43+
if: ${{ github.event.pull_request.head.repo.full_name == 'astral-sh/uv' }}
4244
with:
4345
username: astralshbot
4446
password: ${{ secrets.DOCKERHUB_TOKEN_RO }}
@@ -79,6 +81,48 @@ jobs:
7981
platform=${{ matrix.platform }}
8082
echo "PLATFORM_TUPLE=${platform//\//-}" >> $GITHUB_ENV
8183
84+
- name: Docker apt & pip caches
85+
uses: actions/cache@v4
86+
id: docker-caches
87+
with:
88+
path: |
89+
var-cache-apt
90+
var-lib-apt
91+
root-cache-pip
92+
key: docker-caches-${{ matrix.platform }}-${{ hashFiles('Dockerfile') }}
93+
94+
- name: Docker Cargo caches
95+
uses: actions/cache@v4
96+
id: docker-cargo-caches
97+
with:
98+
path: |
99+
root-target
100+
usr-local-cargo-git-db
101+
usr-local-cargo-registry
102+
key: docker-cargo-caches-${{ matrix.platform }}-${{ hashFiles('Dockerfile', 'crates/**', 'Cargo.toml', 'Cargo.lock') }}
103+
104+
- name: Inject apt & pip caches into docker
105+
uses: reproducible-containers/buildkit-cache-dance@v3
106+
with:
107+
cache-map: |
108+
{
109+
"var-cache-apt": "/var/cache/apt",
110+
"var-lib-apt": "/var/lib/apt",
111+
"root-cache-pip": "/root/.cache/pip"
112+
}
113+
skip-extraction: ${{ steps.docker-caches.outputs.cache-hit }}
114+
115+
- name: Inject Cargo caches into docker
116+
uses: reproducible-containers/buildkit-cache-dance@v3
117+
with:
118+
cache-map: |
119+
{
120+
"root-target": "/root/target",
121+
"usr-local-cargo-git-db": "/usr/local/cargo/git/db",
122+
"usr-local-cargo-registry": "/usr/local/cargo/registry/"
123+
}
124+
skip-extraction: ${{ steps.docker-cargo-caches.outputs.cache-hit }}
125+
82126
# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
83127
- name: Build and push by digest
84128
id: build

Dockerfile

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,25 @@ FROM --platform=$BUILDPLATFORM ubuntu AS build
22
ENV HOME="/root"
33
WORKDIR $HOME
44

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

1419
# Setup zig as cross compiling linker
1520
RUN python3 -m venv $HOME/.venv
16-
RUN .venv/bin/pip install cargo-zigbuild
21+
RUN \
22+
--mount=type=cache,target=/root/.cache/pip \
23+
.venv/bin/pip install cargo-zigbuild
1724
ENV PATH="$HOME/.venv/bin:$PATH"
1825

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

3441
# Build
35-
COPY crates crates
36-
COPY ./Cargo.toml Cargo.toml
37-
COPY ./Cargo.lock Cargo.lock
38-
RUN case "${TARGETPLATFORM}" in \
42+
RUN \
43+
# bind mounts to access Cargo config, lock, and sources, without having to
44+
# copy them into the build layer and so bloat the docker build cache
45+
--mount=type=bind,source=crates,target=crates \
46+
--mount=type=bind,source=Cargo.toml,target=Cargo.toml \
47+
--mount=type=bind,source=Cargo.lock,target=Cargo.lock \
48+
# Cache mounts to speed up builds
49+
--mount=type=cache,target=/root/target/ \
50+
--mount=type=cache,target=/usr/local/cargo/git/db \
51+
--mount=type=cache,target=/usr/local/cargo/registry/ \
52+
case "${TARGETPLATFORM}" in \
3953
"linux/arm64") export JEMALLOC_SYS_WITH_LG_PAGE=16;; \
4054
esac && \
41-
cargo zigbuild --bin uv --bin uvx --target $(cat rust_target.txt) --release
42-
RUN cp target/$(cat rust_target.txt)/release/uv /uv \
55+
cargo zigbuild --bin uv --bin uvx --target $(cat rust_target.txt) --release \
56+
&& cp target/$(cat rust_target.txt)/release/uv /uv \
4357
&& cp target/$(cat rust_target.txt)/release/uvx /uvx
4458
# TODO(konsti): Optimize binary size, with a version that also works when cross compiling
4559
# RUN strip --strip-all /uv

0 commit comments

Comments
 (0)