Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use Docker Compose with images that use the builder-pattern?

I'm aware of the new multi-stage build feature, which works nicely with Docker Compose. However, let's say I'm stuck with the builder-pattern (don't ask)... is there any way to have docker-compose up use the build script required by the builder pattern?

Consider the same builder-pattern files from the linked article:

Dockerfile.build

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN go get -d -v golang.org/x/net/html \
  && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

Dockerfile

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"]

build.sh

#!/bin/sh
docker build -t alexellis2/href-counter:build . -f Dockerfile.build

docker create --name extract alexellis2/href-counter:build  
docker cp extract:/go/src/github.com/alexellis/href-counter/app ./app  
docker rm -f extract

docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app

I could construct a Docker Compose file kinda like this one, but I have no idea how to cp the files from the temporary Docker container.

docker-compose.yml

version: '3'
services:
  app: 
    build: .
    depends_on:
     - app-build
  app-build:
    build:
      context: .
      dockerfile: Dockerfile.build

I could build the temporary Docker image/container and run the cp by using the first part of the build.sh script from above and then using a stripped down compose file, but, then, I might as well just stick with the script.

like image 572
Anthony Mastrean Avatar asked Jul 17 '17 19:07

Anthony Mastrean


People also ask

Does Docker compose run build images?

From your project directory, start up your application by running docker compose up . Compose pulls a Redis image, builds an image for your code, and starts the services you defined.

What is a builder pattern in docker?

The builder pattern describes the setup that many people use to build a container. It involves two Docker images: a "build" image with all the build tools installed, capable of creating production-ready application files. a "service" image capable of running the application.

What is the difference between docker build and Docker compose?

The three primary differences between the Dockerfile and docker-compose are: The Dockerfile is used to build images while the docker-compose. yaml file is used to run images. The Dockerfile uses the docker build command, while the docker-compose.

Do you need Dockerfiles with Docker compose?

Docker compose uses the Dockerfile if you add the build command to your project's docker-compose. yml. Your Docker workflow should be to build a suitable Dockerfile for each image you wish to create, then use compose to assemble the images using the build command.


2 Answers

An approach can be using 2 docker-compose calls, combined with a directory mapping:

version: '3'
services:
  app: 
    build: .

  app-build:
    build:
      context: .
      dockerfile: Dockerfile.build
    volumes:
       - ./build/:/go/src/github.com/alexellis/href-counter/

Then:

#This will produce local ./build/app artifact
docker-compose build app-build

#Having the previous artifact, will use it:
docker-compose build app

Just change this into Dockerfile:

COPY build/app .

However, I recommend you the Multi Stage Build approach. Hugely simpler than this.

like image 69
Robert Avatar answered Nov 15 '22 06:11

Robert


As I understood, you are asking if it is possible to use something like docker cp within the compose file to extract an artifact from the temporary container.

Well, using a shared volume is an option for that.

version: '3'
    services:
      app: 
        build: .
        depends_on:
         - app-build
        volumes:
        - shared:/source        
      app-build:
        build:
          context: .
          dockerfile: Dockerfile.build
        volumes:
        - shared:/output
    volumes:
      - shared:

But you have to add a script in app service which will check if app-build has finished its work and the artifact is ready.

Using shared volumes is a bit risky. You must know what you are doing.

Multiple containers can also share one or more data volumes. However, multiple containers writing to a single shared volume can cause data corruption. https://docs.docker.com/engine/tutorials/dockervolumes/#important-tips-on-using-shared-volumes

There is an issue titled "Add copy to the yaml configuration" on github: https://github.com/docker/compose/issues/1664

I would like to have an option like that in compose file. You can check others' opinions about this on the link above. That issue is closed now but might be opened again.

like image 38
er-han Avatar answered Nov 15 '22 07:11

er-han