Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buildkit multi-stage cache without cargo-chef #57

Open
clux opened this issue Jul 13, 2019 · 10 comments
Open

buildkit multi-stage cache without cargo-chef #57

clux opened this issue Jul 13, 2019 · 10 comments

Comments

@clux
Copy link
Owner

clux commented Jul 13, 2019

Since it's annoying to keep not encouraging multi-stage builds because you cannot reuse a build cache effectively (unless you use cargo-chef in like 4 layers), we should try to get buildkit to cache directly.

Circleci now has orbs, and evars.

@clux clux changed the title buildkit examples buildkit multi-stage Oct 2, 2021
@clux
Copy link
Owner Author

clux commented Oct 2, 2021

Exploring this in kube-rs/version-rs#4 as a way to use muslrust with multi-stage builds without needing cargo-chef, if it works out, I'll port some docs into here.

@clux
Copy link
Owner Author

clux commented Oct 3, 2021

This type of multi-stage dockerfile will work well with DOCKER_BUILDKIT=1:

FROM clux/muslrust:stable AS builder
COPY Cargo.* .
COPY version.rs version.rs
RUN --mount=type=cache,target=/volume/target \
    --mount=type=cache,target=/root/.cargo/registry \
    cargo build --release --bin version && \
    mv /volume/target/x86_64-unknown-linux-musl/release/version .

FROM gcr.io/distroless/static:nonroot
COPY --from=builder --chown=nonroot:nonroot /volume/version /app/
EXPOSE 8080
ENTRYPOINT ["/app/version"]

and caching works great when developing locally.
however github actions' ci strategies only seems to do layer caching (and not save the cache directories) causing full rebuilds on ci. maybe there are some tricks to get this cached as well, but gave up for now.

@clux
Copy link
Owner Author

clux commented Oct 3, 2021

Ah. It's not supported: moby/buildkit#1673 and docker/buildx#399.
Seems actually derided that it's even asked for lol.

@clux clux removed the help wanted label Oct 3, 2021
@clux
Copy link
Owner Author

clux commented Oct 3, 2021

ok moby/buildkit#1512 seems a little more positive at least

@clux clux changed the title buildkit multi-stage buildkit multi-stage cache without cargo-chef May 22, 2022
@sedrik
Copy link

sedrik commented May 24, 2022

Hi just wanted to chime in that I tested a setup like this and locally I still need to rebuild all the deps when I use buildkit's caching. Was that the case for you as well when you tested it? My understanding is that this is one of the things that cargo-chef allows you to bypass.

@clux
Copy link
Owner Author

clux commented May 24, 2022

No, I can actually avoid rebuilding deps and untouched files without cargo-chef:

You can test it out in version-rs with:

DOCKER_BUILDKIT=1 docker build . # full build first time
# edit version.rs
DOCKER_BUILDKIT=1 docker build . # only compiles main executable and links

cargo-chef effectively splatters the relevant cache across docker layers that CI systems like circle/github generally know how to cache, whereas the buildkit cache ends up somewhere in an internal system path that's hard to cache. Works locally, but not on CI :(

@sedrik
Copy link

sedrik commented May 25, 2022

Hmm, ok. I guess I did something wrong in my setup when testing. The question then becomes if it is enough to just cache /var/lib/docker/buildkit or something more fancy needs to happen using buildx for example :/ I guess it needs some investigation

@sedrik
Copy link

sedrik commented May 25, 2022

I ended up doing this based on an article I found. https://medium.com/titansoft-engineering/docker-build-cache-sharing-on-multi-hosts-with-buildkit-and-buildx-eb8f7005918e

It seems to work but I still get the feeling that it sometimes does a complete rebuild but I haven't been able to pin-point the exact issue or when it triggers.

I will continue working on it when I have time over but it seems promising :)

#!/usr/bin/env bash

ECR_REPO=<.....>
IMAGE_TAG=$ECR_REPO:latest

# AWS ECR does not support the builidx cache format, use a private docker hub repo instead
CACHE_TAG=<docker hub repo>:buildx-cache

docker buildx build \
  -t $IMAGE_TAG \
  -f ./Dockerfile \
  --cache-from=type=registry,ref=$CACHE_TAG \
  --cache-to=type=registry,ref=$CACHE_TAG,mode=max \
  --push \
  .```

@clux
Copy link
Owner Author

clux commented May 25, 2022

Thank you, if you find a setup that works that would be super helpful!

btw I think the complete rebuild happens when the github cache reaches 10G and it starts cycling away layers.

@sedrik
Copy link

sedrik commented May 25, 2022

Ah no, I have only tested it locally, also the cache is stored on docker hub in this case. I will look at testing it on Github when I have a night over to play with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants