Slide 1

Slide 1 text

Create lean Docker images using the Builder Pattern GoSheffield - December 6th

Slide 2

Slide 2 text

Hello! I’m Mike Kaperys. I currently work at U Account (@uaccount - uaccount.uk) as Senior Software Engineer. Developer since 2012. Writing Go since 2016. @_kaperys kaperys.io [email protected]

Slide 3

Slide 3 text

The problem

Slide 4

Slide 4 text

Vision App Small Go web app which submits webcam images to AWS’ Rekognition API. kaperys/blog/docker-builder-pattern func main() { svc := rekognition.New(session.New(&aws.Config{Region: r := gin.Default() r.StaticFS("/", http.Dir("html")) r.POST("/analyse", func(c *gin.Context) { var req struct{ Image string } if err := json.NewDecoder(c.Request.Body). Decode( c.AbortWithError (http.StatusBadRequest, er return } img, err := base64.StdEncoding. DecodeString(req. if err != nil { c.AbortWithError (http.StatusInternalServer return } labels, err := svc.DetectLabels(&rekognition.Det if err != nil { c.AbortWithError (http.StatusInternalServer return } if len(labels.Labels) == 0 { c.JSON(http.StatusOK, nil)

Slide 5

Slide 5 text

FROM golang:latest ADD . /go/src/github.com/kaperys/blog/docker-builder-pattern WORKDIR /go/src/github.com/kaperys/blog/docker-builder-pattern RUN go get RUN go build -o server . ENTRYPOINT [ "./server" ] Dockerfile

Slide 6

Slide 6 text

FROM golang:latest ADD . /go/src/github.com/kaperys/blog/docker-builder-pattern WORKDIR /go/src/github.com/kaperys/blog/docker-builder-pattern RUN go get RUN go build -o server . ENTRYPOINT [ "./server" ] Read-only base image Writable space Read-only layer Read-only layer Read-only layer Read-only layer Read-only layer container

Slide 7

Slide 7 text

docker build -t vision-app .

Slide 8

Slide 8 text

Why so large? The golang:latest image is based from Debian 9 and contains the latest Go compiler and tooling. We’ve added our raw source code and vendored code. We’re creating unnecessary layers in the final image by issuing multiple RUN instructions. twitter.com/ashleymcnamara

Slide 9

Slide 9 text

We don’t need this stuff in production.

Slide 10

Slide 10 text

Multi-stage builds ● Docker 17.05 introduced multi-stage builds. ● Multi-stage builds allow for multiple FROM instructions in a single Dockerfile. ● Using a multi-stage build enables abstraction of concerns when building images. Typically, the two concerns are build-the-thing and run-the-thing. ● Each FROM instruction begins a new build stage. ● Files can be transferred between build stages using the COPY --from= instruction.

Slide 11

Slide 11 text

FROM golang COPY ${pwd} /go/src/github.com/kaperys/blog/docker-builder-pattern WORKDIR /go/src/github.com/kaperys/blog/docker-builder-pattern RUN go get && CGO_ENABLED=0 GOOS=linux go build -o server . FROM scratch LABEL maintainer="Mike Kaperys " COPY --from=0 /go/src/github.com/kaperys/blog/docker-builder-pattern/server /opt/kaperys/vision/server COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt ADD html/ /opt/kaperys/vision/html EXPOSE 8080 WORKDIR /opt/kaperys/vision ENTRYPOINT [ "./server" ] Dockerfile

Slide 12

Slide 12 text

docker build -t vision-app .

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

98% reduction Our original image was 920MB. We’ve been able to reduce this to 18.2MB (our compiled binary is only 18MB!) by using the builder pattern.

Slide 15

Slide 15 text

Thanks! Questions? @_kaperys