Multistage Docker Builds

April 29, 2017
docker engineering development

I talked about how to create slim containers with only the necessary dependencies to run your applications in the past, but now next release of docker features multistage containers that reduce the complexity of having a build container and them copying your final application to a run container.

More in-depth details about what multi-stage builds are can be seen in this 2 github issues #32063 and #31257

Docker multi-stage builds are available starting v17.05.0-ce-rc1 and v17.05.0-ce-rc2, if your using Mac using latest release of beta channel will be enough to start using this.

What before was 2 containers and 2 dockerfiles we can now reduce to:

# Build stage
FROM lacion/docker-alpine:gobuildimage AS build-stage
ENV GOROOT=/usr/lib/go \
    GOPATH=/gopath \
    GOBIN=/gopath/bin \
    PROJPATH=/gopath/src/github.com/lacion/foo
# Because of https://github.com/docker/docker/issues/14914
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin

ADD . /gopath/src/github.com/lacion/foo
WORKDIR /gopath/src/github.com/lacion/foo

RUN make build-alpine

# Final Stage
FROM lacion/docker-alpine:latest

ARG GIT_COMMIT
ARG VERSION
LABEL REPO="https://github.com/lacion/foo"
LABEL GIT_COMMIT=$GIT_COMMIT
LABEL VERSION=$VERSION

# Because of https://github.com/docker/docker/issues/14914
ENV PATH=$PATH:/opt/foo/bin

WORKDIR /opt/foo/bin

COPY --from=build-stage /gopath/src/github.com/lacion/foo/bin/foo /opt/foo/bin/
RUN chmod +x /opt/foo/bin/foo

CMD /opt/foo/bin/foo

All of this means, we can now reduce the amount of code to maintain and the complexity of it, it also means our makefiles will be less complex and easier to understand.

comments powered by Disqus