Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 
like image 585
Nick Avatar asked Nov 30 '16 22:11

Nick


People also ask

Why is docker compose recreating?

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.

What is multistage build in docker?

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.

How do you handle multiple docker compose?

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 .

Can a project have multiple Dockerfiles?

As Kingsley Uchnor said, you can have multiple Dockerfile , one per directory, which represent something you want to build.


2 Answers

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 
like image 182
amath Avatar answered Sep 18 '22 19:09

amath


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.

like image 42
luckydonald Avatar answered Sep 18 '22 19:09

luckydonald