TransWikia.com

Multistage builds with yum

Stack Overflow Asked by Vorticity on November 4, 2021

I’m struggling with converting my current dockerfiles to multistage builds to cut out some cruft. I start from a base image, install a bunch of stuff via yum along with a bunch of other packages that I install from source.

At this point, I would like to start with a fresh image and bring in only the packages installed via yum and the binaries from my installations from source. I see three ways to do this, but I don’t like the first option and don’t know how to do the other two.

Option 1

Build a separate Dockerfile for the yum install, then use that as my base image prior to the installations from source.

I don’t like this option because it adds more to my build workflow. It would be nice to have everything contained in one Dockerfile. Maybe this is the way I need to go, though.

Option 2

Install packages via yum in a different directory and copy across to the next stage of the build.

I have found that I can install packages in a non-default directory via yum install --installroot=/foo --releasever=/ packagename, however, this installs all requirements to /foo rather than continuing to use packages installed in /usr, causing the image to grow significantly.

Is there a way to install packages via yum in a different directory, but have it continue to resolve its dependencies from the default directory?

Option 3

Install packages via yum, then start the next build stage from the point after the yum packages have been installed.

Is there a way to use the layer resulting from a build stage as the start of the next build stage? Something like this:

FROM centos7 as first
RUN some stuff
FROM first as second
RUN some stuff
FROM second
COPY --from=second ...

3 Answers

You have the right idea with option 1, but with multistage builds, you can accomplish this by using a 3 stage build rather than a separate base image docker file.

Using the combination of named stages, copying from a previous stage, and starting a stage from a previous stage, the result would look like the following.

FROM centos:latest AS yum-base
RUN yum install -y LIST_OF_YUM_DEPENDENCIES
...

FROM yum-base AS compiled_packages
RUN build_some_binaries_here
...

FROM yum-base
COPY --from=compiled_packages /usr/local/bin/file_name /usr/local/bin/file_name

Answered by jebentier on November 4, 2021

Use multi-stage builds

With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image. To show how this works, consider this example:

Dockerfile

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 CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"] 

You only need the single Dockerfile. You don’t need a separate build script, either. Just run docker build.

$ docker build -t alexellis2/href-counter:latest .

The end result is the tiny production image, with a significant reduction in complexity. You don’t need to create any intermediate images and you don’t need to extract any artifacts to your local system at all.

How does it work?

The second FROM instruction starts a new build stage with the alpine:latest image as its base. The COPY --from=0 line copies just the built artifact from the previous stage into this new stage. The Go SDK and any intermediate artifacts are left behind, and not saved in the final image.

Answered by CanciuCostin on November 4, 2021

I am not sure if that's doable via Docker, but it looks like a good use case for http://drone.io/ You can use different images at different stages of the build, and then use only files you want on the final docker image.

Answered by alfheim on November 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP