habitus icon indicating copy to clipboard operation
habitus copied to clipboard

Dockerfile.generated race with same Dockerfile and different build args

Open grugnog opened this issue 5 years ago • 3 comments

build.yml looks something like:

build:
  version: 2016-03-14 # version of the build schema.
  steps:
    v1:
      name: v1
      dockerfile: Dockerfile
      args:
        version: 1
    v2:
      name: v2
      dockerfile: Dockerfile
      args:
        version: 2

What happens is that the Dockerfile.generated is the same filename and path. Both builds proceed in parallel (using whichever file was created last). As soon as the first build finishes the Dockerfile.generated is removed and so the second build errors with "Build for step v2:latest failed due to remove dir/Dockerfile.generated: no such file or directory".

I think the solution for this would be to either encode the build args in the filename for Dockerfile.generated (probably in the form of a hash) or generate a random token to the file and track that through the lifecycle of the build. The latter seems like the simpler approach, since it seems likely there is other data (perhaps the context directory, for example) that could affect the build and would need to be included in the hash.

grugnog avatar Feb 25 '19 22:02 grugnog

For anyone else with the same issue, it seems that you can work around this by using depends_on to ensure they build in serial and don't step on each others toes.

grugnog avatar Feb 25 '19 22:02 grugnog

Thank you @grugnog for the suggestion. It makes sense to use depends_on to avoid a race condition, however I'd like to know what you need to achieve so probably we can make changes to accomodate that without serialising the builds.

khash avatar Feb 28 '19 14:02 khash

I think the use case described in my example is probably a good one to work from. We want to allow a single Dockerfile to build different versions of the same program, so (rather than duplicate the Dockerfiles or build some templating system) we use build args to inject the version we want to build. In this case the 2 builds are totally independent, so the depends_on is really just a workaround - a better result would be to have the Dockerfile.generated file name include a hash or random token, so that the builds can be run in parallel.

grugnog avatar Feb 28 '19 23:02 grugnog