How to prevent docker-compose building the same image multiple times?
My docker-compose.yml
specifies multiple images. Two of these images are built using the same local Dockerfile
. They share the same image name but each has a different command.
During development, I frequently use docker-compose up --build
to rebuild the images. The trouble is that docker builds the same myimage
twice - taking longer than necessary.
Is there a way to express that the image only needs to be built once?
version: '2'
services:
abc:
image: myimage
command: abc
build:
context: .
dockerfile: Dockerfile
xyz:
image: myimage
command: xyz
build:
context: .
dockerfile: Dockerfile
Per the docker-compose file documentation for build, specify build:
and image:
for the first service, and then only image:
for subsequent services.
Here's a modified version of your example that only builds the image once (for abc service) and reuses that image for xyz service.
version: '2'
services:
abc:
image: myimage
command: abc
build:
context: .
dockerfile: Dockerfile
xyz:
image: myimage
command: xyz
You can fake a build only service to build the image, and then use dependencies to that for the actual workers. That has the advantage that you don't have one of those services automatically start if you wanna start the others.
you need to add an image name to specify build:
and image:
for the build service, as well as make sure it terminates and never restarts automatically.
Then image:
and depends_on: first_service
for your services.
like so:
version: '2'
services:
_myimage_build:
image: myimage
command: ['echo', 'build completed'] # any linux command which directly terminates.
build:
context: .
dockerfile: Dockerfile
first_service:
image: myimage
depends_on:
- _myimage_build
command: abc
second_service:
image: myimage
depends_on:
- _myimage_build
command: xyz
thanks to @amath for their answer.
To make @amath good answer a bit clearer
you need to add an image name to specify build:
and image:
for the first service, and then image:
and depends_on: first_service
for subsequent services.
like so:
version: '2'
services:
first_service:
image: myimage
command: abc
build:
context: .
dockerfile: Dockerfile
second_service:
image: myimage
command: xyz
depends_on:
- first_service
thanks to @DrSensor for the comment