-
Notifications
You must be signed in to change notification settings - Fork 93
Add build caching to docker #810
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
Conversation
Signed-off-by: Aaron Sutula <hi@asutula.com>
yessss, so good. def not an expert here, but the original build backend to docker of course had this annoying sequential-build-step-execution thing. fortunately the "multi-stage build" stuff made things a little better by grouping build stages into logical "build tasks".... and those "build tasks" had the nice property of being totally independent, which means in theory they could be executed in parallel. so i think that's what buildkit takes advantage of. it creates a graph of those dependencies between "build tasks" so that it can easily track which parts of the build can be totally ignored, executed in parallel vs. sequentially, etc. assuming that's correct, it's a pretty nice optimization. yay graphs. :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
The explanation is actually much simpler :)
The Go compiler has a build-cache that it's saved in GOCACHE
environment variable path folder. It does that's done by default and not related to Docker.
What this change is doing, is caching that folder in a docker cache, similar-ish to the onion-layer caching that Docker does but you can select the target folder (in this case, the $GOCACHE
folder).
This is basically what happens if you compile things in your own machine. You have previously built dependencies cached in $GOCACHE
, so next time it builds the binary, it leverages work existing there.
Yep, that's correct but there's no much room for parallelization in our build pipelines (in all our repos). :) What we really leverage of multi-stage pipelines is building the final artifact in a smaller base-image without any temporal/garbage side-products (dependencies, build caches, source code) of the build stage. So the final Docker image is simply a small base image, plus only the binary from the build stage. What this PR does to make things faster, is having a way to cache part of the |
Oh interesting! I'm definitely learning something new about builds here. :) @asutula super curious, do you a have a sense for how much faster it is after the change? |
Maybe related to my version of Docker Desktop, but I'm getting caching out-of-the-box:
See following log output gives a hint:
Following the link in the message...
BuildKit is enabled by default. Output of
This is the Apple M1 alpha: https://docs.docker.com/docker-for-mac/apple-m1/ |
@eightysteele re: your question
For building Powergate on my machine, it was taking about 1 min with no caching. With a cache in place and no code changes, the build was instantaneous. If I changed code in one file, the build takes about 2 seconds. |
@sanderpick how can you tell from that output that BuildKit is enabled by default for you? |
The output says "Building with native build." and provides a link that describes what native build means: Building with the docker CLI, which it says has BuildKit enabled by default. |
Ah gotcha, thanks. |
Signed-off-by: Aaron Sutula <hi@asutula.com>
…ergate into asutula/docker-build-cache
Still trying to understand how exactly this works and what exactly BuildKit is, but this simple change seems too good to be true. Caches build objects and speeds up docker builds by many many times. Based on what I was reading in this blog post and the others in the same series: https://www.docker.com/blog/containerize-your-go-developer-environment-part-2/