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.
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.
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.
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.
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.
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.
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.
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