Split up library builds into individual builder stages to preserve layer cache #343
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Why
Hello! I've noticed the docker image is quite hefty, and I was curious if I could improve it a bit. After taking a look, I realized I couldn't help much with reducing the image size 😆 .... but I thought it might be possible to improve layer reuse between builds. In the end, this feature branch is only 7.98mb smaller then whats on
master
, but I believe layer reuse is now a possibility depending on how the builds and caching are set up.If no one thinks this PR provides any value, that’s no problem! It does introduce a bit more complexity, so I totally understand. Anyway, on to the changes I made:
What
I've moved each major build phase into its own builder stage using multi-stage builds:
ssocr
,pip
,libcec
,PicoTTS
, andTelldus
. The results of those builder stages are then copied out into the 'main' stage. All temporary files were already being pruned nicely, so again, no real space savings. However, using theCOPY --link
command from the builder stages enables this cool docker feature:So, if you need to bump a version in
requirements.txt
, usingCOPY --link
will allow those other layer - likessocr
- to remain unchanged. Pretty cool! If this PR works as expected, I hope that the next time I rundocker compose pull
, it will require fewer layers to be pulled.Now... there is a bit of a gotcha with all this. This caching logic only works if the builds are correctly set up with caching. For example,
docker-compose
builds cannot create a multi-stage build cache. Looking around, I seebuildx
is being used over athome-assistant/builder/
, but there was a lot of logic going on, and I couldn't quite follow it all.So, there's a chance some follow-up changes might be needed before the benefits of this PR can be realized - for example, using
cache-to
and ensuringmode=max
is set to enable the mutli-stage build cache. But one step at a time - if you all think this is an improvement worth making, we can iterate from here.Testing
For testing, I ran the build and verified that it runs. However, that doesn’t fully confirm that the libraries I modified are still being installed correctly. Some follow-up work is definitely required to verify everything is functioning as expected.