-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Local docker builder should support using the previously built image as a cache source #6809
Comments
@artemkoru would you mind taking a look at the solution implemented in #5903 for GCB? It seems more straightforward and less error-prone. |
Hi, @briandealwis! Unfortunately we can't use GCB! Our pipelines works on Github Actions, also we don't use self-hosted custom runner (We can't use "local cache"). We try to use this Github action for caching Docker layers. But we are faced with the problem, which is that the size of the cache (docker images) every time increases more and more. The problem describes here. We tried some of the solutions suggested there but ended up giving up. I understand that using the Skaffold build hook for adding additional tags looks a little strange. But it's temporary solution and I can't do this via Skaffold any other way. Add some additional docker-tags to each artifact will be better solution when it will come. All I want to suggest it's adding support to allow using environment variables in the parameter build.artifacts[*].docker.cacheFrom. As I see it does not contradict the Skaffold approaches. I think it will be helpful for other users in similar cases. Will be grate if you accept these changes. Thanks! |
Sorry @artemkoru I meant implement the equivalent handling for the docker builder too. |
@briandealwis Thanks for your comment i didn't understand it. I try to check it with this skaffold.yaml: apiVersion: skaffold/v2beta25
kind: Config
metadata:
name: multistage-build-and-cache
build:
artifacts:
- image: builder
context: .
docker:
dockerfile: Dockerfile
target: builder
cacheFrom:
- builder
#- artemkoru/builder:latest #we don't use latest tags
buildArgs:
BUILDKIT_INLINE_CACHE: "1"
- image: app
context: .
requires:
- image: builder
alias: BUILDER
docker:
dockerfile: Dockerfile
local:
useBuildkit: true
tagPolicy:
gitCommit:
ignoreChanges: true My Dockerfile:
I always get this warning and error messages:
Full logs:
If I run it again, clearing all local caches, the runtime is equivalent. What am I doing wrong? And the second question: if we will use the customTemplate image tagger how will it find the previous image tag? Thanks! |
Oops I meant that if you were interested then you could try implementing a fix for the docker builder using the same approach used in the gcb build. |
@briandealw sorry for the delay, as I understand your approach is using the same image tag in the cache that will be built and this doesn't solve my problems that I described above, because any time the image tag will be different. Or am I misunderstanding something? |
With #5903, the GCB build will replace an image in the
Then the Let us know if you'd like to take a stab at bringing this over to the local Docker builder. In the meantime, I'll retitle this issue. |
Yes, I understand it! Let's imagine that what you propose has already been implemented and consider how it works. skaffold.yaml; apiVersion: skaffold/v2beta25
kind: Config
metadata:
name: multistage-build-and-cache
build:
artifacts:
- image: multistage-build-and-cache-builder
context: .
docker:
dockerfile: Dockerfile
target: builder
cacheFrom:
- multistage-build-and-cache-builder
buildArgs:
BUILDKIT_INLINE_CACHE: "1"
local:
useBuildkit: true
tagPolicy:
gitCommit:
ignoreChanges: true Initial state: Case 1I made a git-commit (let's imagine the hash will be like this Then, I changed the app code and made an other git-commit (it's hash is Case 2I know you wrote that you use only tagPolicy:
envTemplate:
template: "{{.ENV}}" where ENV is an environment variable containing the name of the current environment. In this case I will get a static docker tag for each environment. And your solution will work fine. But we have another problem: if I try rollback (e.g. helm rollback) the deployment will be failed, because the image with this tag was overwritten and the sha256 hash won't match. Also I am unable to deploy the previously builded artifacts, the same reason. To solve this problem, you can propose to implement overrides "tagpolicy" per artifact (not multiple tags per artifact). SummaryI am going to try implement your solution soon, I would also be grateful if you tell me what you think about the problems that I described above. Thanks! |
@artemkoru In Case 1, I think you're confusing a hash (which is computed based on the source contents) with the tag. But since the tag is computed on each build, it's possible that generated tag may differ on the each pass and the cache may not work. For example, if first building from a pristine repo and then making a change, the gitCommit tag for the second iteration will have a Using a development-time tagging policy would also avoid the issue in Case 2. But IMHO you shouldn't be relying on image tags, which are mutable: your Helm chart should be referencing the image by its digest. That way a rollback will get exactly the image that was used previously, regardless of the tag. |
If using a CI/CD pipeline to build/push/deploy only on pushes to main, then I think it should be fine to use use commits instead of hashes. It's also a bit easier to reason about in the artifact registy, as opposed to using "latest" tags. In our case, we have a Kubernetes Job run from a manual GitHub worfklow dispatch on main. It uses the most recent commit as the image tag when installing a Helm chart for the job (not installed via Skaffold). This tag references an image already built and pushed in a separate deployment workflow. How could we set this image tag if using a digest? The process would become quite involved. Moreover, I can't think of any good reason why a dirty commit would be used as a tag when deploying to a remote cluster. We only use "latest" tags for a +1 on being able to use the |
I want to make cache of docker’s layers «builder» stage using the cache-from flag, like this #3831.
I can do like this:
It works fine, but we also have dynamic environments. In this case the skaffold.yaml should look like this:
If I try to use this configuration, I got the error:
I would suggest to allow using environment variables in the parameter
build.artifacts[*].docker.cacheFrom
. It solves this problem.What do you think about this? Thanks.
As I understand these changes are enough artemkoru@7af8afd. I can create PR, if it's ok.
Sample project here: https://github.com/artemkoru/multistage-build-and-cache
P.S. Also will be great if we will can add some additional docker-tags to each artifact, which was suggested here #1269
The text was updated successfully, but these errors were encountered: