68

Please help me understand the difference between 'image' and 'build' within docker compose

meallhour
  • 13,921
  • 21
  • 60
  • 117

3 Answers3

64
  • image means docker compose will run a container based on that image
  • build means docker compose will first build an image based on the Dockerfile found in the path associated with build (and then run a container based on that image).

PR 2458 was eventually merged to allow both (and use image as the image name when building, if it exists).

therobyouknow mentions in the comments:

dockerfile: as a sub-statement beneath build: can be used to specify the filename/path of the Dockerfile.

version: '3'
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
Grant Wu
  • 47
  • 5
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 4
    `dockerfile:` as a sub-statement beneath `build:` can be used to specify the filename/path of the Dockerfile - https://docs.docker.com/compose/compose-file/#build – therobyouknow Jun 15 '18 at 13:25
  • 1
    @therobyouknow Thank you. I have included your comment in the answer for more visibility. – VonC Jun 15 '18 at 17:38
  • 1
    +1 thanks @VonC. I should also say that I believe that if the `dockerfile:` statement optionally isn't present, then docker-compose will look for the file named `Dockerfile` in the directory that docker-compose was launched from (i.e. the same folder within where the docker-compose.yml file resides). If there is a (relative) path specified directly after the `build:` statement (which also means no sub-statements), then docker-compose will look in there for the Dockerfile. The other way to specify a directory is by using the `context:` sub-statement with the path (as your example shows). – therobyouknow Jun 15 '18 at 23:01
  • These options for specifying the Dockerfile are explained in the documentation, here: https://docs.docker.com/compose/compose-file/#build (thank you for reading my comments and feeding back.) +1 upvoted your answer and the original question. – therobyouknow Jun 15 '18 at 23:02
  • 2
    What happens if we use both image and build? is there a priority between them or always the second one gets used? – Amin Bashiri Jul 25 '21 at 05:37
  • @AminBashiri You could not use it within the same `service:`. But you can use them both in the same `services:` Dockerfile, with `depends_on` to make sure the build is done first. https://github.com/compose-spec/compose-spec/blob/master/spec.md#depends_on – VonC Jul 25 '21 at 11:55
  • what I have seen is using `docker-compose -f a.yml -f b.yml` and for a particular service, it uses build in one file and image in the other. – Amin Bashiri Jul 26 '21 at 11:23
  • @AminBashiri OK. I didn't know it could work for the same service. – VonC Jul 26 '21 at 11:55
7

build: expects dockerfile path as an argument, it will build an image first and then use the image to create a container.

image: expects existing image name as argument , it will launch container using this image.

Example:docker-compose.yaml

version: '3'
services:
  service1:
    build: .
    ports:
      - "5000:5000"
  service2:
    image: "redis:alpine"

service1 will build an image first based on Dockerfile of current path and run container based on this image.

service2 will download "redis:alpine" image from docker hub and run container on downloaded image.

Shahid Hussain
  • 1,599
  • 1
  • 20
  • 24
3

Official documentation that goes in depth on the difference between build and image might be of some help here. https://docs.docker.com/compose/compose-file/build/ Long story short, build needs the path to a Dockerfile that it can use to build an image, but image goes to a repository to grab an existing image. Both can be included for a service, but

When a service definition includes both the image attribute and a build section, the Compose implementation can’t guarantee a pulled image is strictly equivalent to building the same image from source. Without any explicit user directives, the Compose implementation with Build support MUST first try to pull the image, then build from source if the image was not found on registry. The Compose implementation MAY offer options to customize this behaviour by user request.

  • In my case, `docker-compose up` would build the image, `docker compose up` would pull then build the image. I haven't found a way for "pull if exist, build if not". – user1473249581 Jun 21 '23 at 07:47