buildkit: bug: buildkit does not consider ONBUILD COPY --from
Hi, we make heavy use of ONBUILD option in our environment.
Our typical Dockerfile looks like this:
FROM my.company.com/ci/dotnet:v1-build as build
FROM my.company.com/ci/dotnet:v1-runtime
This works fine in legacy docker build, but turning on BUILDKIT option activates some optimizations, so docker tries to build these containers in parallel. The problem is containers are dependent:
-
my.company.com/ci/dotnet:v1-build:
FROM base:v1 WORKDIR /src ONBUILD COPY . /src ONBUILD make clean all -
my.company.com/ci/dotnet:v1-runtime:
FROM runtime:v1 WORKDIR /app ONBUILD COPY --from=build /src/target /app
Running DOCKER_BUILDKIT=1 docker build . results in:
DOCKER_BUILDKIT=1 docker build .
[+] Building 0.8s (8/8) FINISHED
...
=> ERROR [stage-2 3/1] COPY --from=build /src/target/ /app 0.0s
------
> [stage-2 3/1] COPY --from=build /src/target/ /app:
------
not found: not found
My questions are:
- Can I turn off these optimizations to run builds sequentially?
- Is there a way to mark these stages as dependent explicitly?
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 37
- Comments: 43 (7 by maintainers)
Commits related to this issue
- Updated docs to include workaround See: https://github.com/moby/buildkit/issues/816#issuecomment-581926095 — committed to vexxhost/docker-openstack-builder by mnaser 2 years ago
Just chiming in here - we do the same as @astorath at our company. It’s been a godsend for enabling extremely efficient / modular builds and dockerfiles
For context: We discovered this issue after trying to use (new) build secrets (with buildkit)
I think this solution is born out of the need to create
Dockerfiles for a lot of similarly structured projects combined with an attempt to follow best practices. Let’s say you have a setup where:buildstage takes your source and produces some binariesruntimestage copies/installs the binaries into the production imageThis is, of course, trivial to achieve with multi-stage and that’s the recommended approach (keeping build and runtime environments separate). However, this doesn’t really scale well, as you’d need to repeat this same
Dockerfilefor 10, 20 or even 50 projects (not uncommon for systems powered by microservices).Before BuildKit, (arguably) the neatest way to achieve this was with multi-stage
ONBUILDfiles. It enables developers to write extremely modular/reusableDockerfiles, whilst keeping Docker workflows native (docker/docker-compose build just works).Given BuildKit feature set, I agree that the solution no longer seems like a great fit. @tonistiigi is the vision to fill this gap with custom BuildKit frontends?
If the path forward is via BuildKit custom frontends, it’d be great to make dockerfile.Build more easily extensible. Creating a custom frontend is quite an undertaking today, as it requires a lot of specialist knowledge (LLB) and boiler plate code (not to mention additional duplication if the end goal is to use Dockerfile syntax). It’d be awesome if there was a simpler API for this to match the learning curve of multi-stage
Dockerfiles. For example, what I can imagine doing is:Dockerfilesimilar to below:Dockerfilelook something like this:What are you thoughts on this?
Here is the switch https://github.com/companieshouse/ch.gov.uk/pull/192
Just set environment arg
DOCKER_BUILDKIT=0beforedocker buildHey folks 👋 Docker Desktop 2.4.0.0 enables BuildKit by default now, which will potentially break any
Dockerfiles dependent on this functionality. I’m happy to work with maintainers to get this addressed if capacity is an issue here (will possibly need some pointers on where to start though). It looks like @tonistiigi’s suggestion could be a way forward:FROMsONBUILD--from)@tonistiigi
Well, this is not my invention, https://engineering.busbud.com/2017/05/21/going-further-docker-multi-stage-builds/ - this is one of the first google search results. So I don’t think I’m alone here.
@thaJeztah
Maybe this is confusing for official images, but for multistage internal images designed for that purpose - ONBUILD is a revelation…
Down the link above is a nice solution to the problem: if we could use something like:
we won’t need this strange hack.
Hi, so there going to be some fix or you’re just breaking backward compatibility by literally saying “you always do it wrong way, our way is better! Just do refactoring of all your dockerfiles and ci/cd”? )
Ditto, when is this getting fixed?
Quote from https://engineering.busbud.com/2017/05/21/going-further-docker-multi-stage-builds/:
As the author of the multi-stage PR I can confirm I was not clever enough to see it as a possible feature.
Just for the sake of adding another usage example of this (now missing) feature: https://github.com/r2d2bzh/docker-build-nodejs
This project started internally 3 years ago. At this time it was designed this way after reading the article pointed by @astorath in a previous comment and it also closely relates to the situation described by @EricHripko.
Many of us are still not using buildkit. This means that, for now, we have to support both the pre-buildkit and post-buildkit environments. The only way to do that ATM is to provide two different build methods, one for non-buildkit users and another for buildkit users.
What is also clearly odd for someone using the docker compose plugin is that these errors start popping between versions 2.3.3 and 2.3.4 of the plugin. It took me at least an hour to relate these behaviors to this issue, this is OK but perhaps having a warning on this particular subject in the Dockerfile reference (or somewhere else) might be helpful to spot or avoid the issue more easily. I can help documenting this, provided the proper guidance.
This is a very weird (and inventive) way to use
COPY --from.No, we don’t want to add any special behavior for this. Either we consider this as bug and just fix the image resolution or we document that this is invalid usage (and make it error with a proper message).
A problem with implementing this is that we can’t start to process all stages in parallel like we do now because we only know about the dependant images after we have pulled the config of the base. Still doable, just adds complexity. Once we have determined the correct dependencies of the stages it would build in regular concurrent manner.
@AkihiroSuda @tiborvass @ijc @thaJeztah get your votes in
Any update? As we now see:
This will kill all our builds.
@softworm This does not solve the problem. Turning off BuiltKit means you cannot use the secrets mechanism, which is the only decent approach for passing secrets into a build.
any update? same issue on multi-stage
ONBUILDcopy.For anyone that loves to work on this issue, I’ve included steps to reproduce the issue in moby/moby#42845 and kept those as simple as possible.
Note that the use of images instead of stage names in
COPY --fromis not documented, so you should use probably stage aliases as shown../template/Dockerfile:
./project/Dockerfile: