compose: Don't build the same thing twice
Even though Docker caches layers and the second build is fast, it’s not necessary for Compose to build the same thing twice. As far as I can tell, if two services in the yaml have exactly the same string, you can be sure they will be exactly the same build:
21:02 ~/docker/test $ cat fig.yml
svc1:
build: oog
svc2:
build: oog
21:02 ~/docker/test $ fig build
Building svc2...
---> e72ac664f4f0
Successfully built e72ac664f4f0
Building svc1...
---> e72ac664f4f0
Successfully built e72ac664f4f0
Naturally, the image built is the same for both services.
There’s also the question of the race condition if someone edits the Dockerfile while fig is already building. This is a bit contrived, but does work:
$ cat fig.yml
svc1:
build: oog
svc2:
build: oog
$ diff oog/Dockerfile[12]
3c3
< && echo hi
---
> && echo bye
$ ( cd oog;ln -sf Dockerfile{1,} ); fig build --no-cache & ( cd oog;sleep 2;ln -sf Dockerfile{2,} ); fg
[1] 1374
Building svc2...
---> e72ac664f4f0
Step 1 : RUN sleep 5 && echo hi
---> Running in dd0c813779ec
fig build --no-cache
hi
---> 9f1aed6d839c
Removing intermediate container dd0c813779ec
Successfully built 9f1aed6d839c
Building svc1...
---> e72ac664f4f0
Step 1 : RUN sleep 5 && echo bye
---> Running in 3c7d54f6145a
bye
---> 02ece1cf8f17
Removing intermediate container 3c7d54f6145a
Successfully built 02ece1cf8f17
Contrived or not, if it didn’t attempt to run the same build twice, it wouldn’t have divergent images.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 45
- Comments: 35
I’ve managed this issue in the following way:
I’m trying to use compose to launch multiple containers from the same image but with a different command. Running
docker-compose up
causes the same image to be built a couple of times, which can take a long time depending on the number of containers I’m launching.Right now, my workaround is to build and tag the image separately, and then reference it from the compose configuration file. However, this requires other developers on my team to be aware that just running
docker-compose up
does not work unless you have previously built and tagged the image.I think this could be addressed in compose if there was a way to reference built images within the
docker-compose.yml
file.As of Compose 1.6.0 you can use both
image
andbuild
together to do just that. You can optionally build the image outside of compose, andup
will just use the image you built, but if someone else runsbuild
, it will do the right thing and build the same tag.I’m on
compose
v2.12.1, for some reasons I had to addpull_policy: never
to all services, so that they don’t try to pull from docker hub.doesn’t work now =(
Both docker-compose in latest releases and Compose V2 use BuildKit as a builder backend, and this one manage building images in parallel with deduplication for equivalent Dockerfiles in compose services.
I recommend using Procfile with overmind / hivemind / foreman
just write a separate docker-compose file specially for build for example:
What about using partial images?
Generate an image with all common factors and build on top of it.
This may also be resolved together with #1896, though I believe we actually need actually more decoupling of building and running (Only-build/partial images, which would allow devs to use “FROM” to build on top of it), while also allowing for granular control during run-time, which in the end could amount to 2 separate, albeit somewhat related, issues. Depends a lot on the design.
My suggestion would be for the Compose-File to allow two new keys,
images
andcommands
. Relating to this issue,images
would only build and serve as basis for the services. The keycommands
would be related to #1896.Here is the current link for docker-compose file reference build