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
If there are existing containers for a service, and the service's configuration or image was changed after the container's creation, docker compose up picks up the changes by stopping and recreating the containers (preserving mounted volumes). To prevent Compose from picking up changes, use the --no-recreate flag.
A multistage build allows you to use multiple images to build a final product. In a multistage build, you have a single Dockerfile, but can define multiple images inside it to help build the final image.
Running Multiple Copies of a Single Compose Project For times when you need multiple copies of environments with the same composition (or docker-compose. yml file), simply run docker-compose up -p new_project_name .
As Kingsley Uchnor said, you can have multiple Dockerfile , one per directory, which represent something you want to build.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With