82 lines
2.2 KiB
Markdown
82 lines
2.2 KiB
Markdown
---
|
|
title: Separate Build Image
|
|
---
|
|
## Overview
|
|
|
|
Making lightweight docker images is key to having a fast development/deployment pipeline. For compiled code, building the binary inside a docker container has the benefit of being a repeatable and standardised build process. However, this can create a very large images which can become an issue down the line.
|
|
|
|
## Our code
|
|
|
|
In this example, we will use a simple webserver writen in [Go](https://golang.org/). The following code is just a simple hello world webserver listening on port `8080`.
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
)
|
|
|
|
func handler(w http.ResponseWriter, r *http.Request) {
|
|
fmt.Fprint(w, "Hello world!")
|
|
}
|
|
|
|
func main() {
|
|
http.HandleFunc("/", handler)
|
|
log.Fatal(http.ListenAndServe(":8080", nil))
|
|
}
|
|
```
|
|
|
|
### Dockerfile
|
|
|
|
The Dockerfile for this code might look something like this
|
|
|
|
```
|
|
FROM golang:1.11
|
|
|
|
ADD . /app
|
|
|
|
WORKDIR /app
|
|
|
|
RUN go build -o /myserver .
|
|
|
|
EXPOSE 8080
|
|
|
|
CMD [ "/myserver" ]
|
|
```
|
|
|
|
Building this image results in an image with a size of 783MB!! With an image that size for a simple application, it's easy to see how this can slow things down when deploying.
|
|
|
|
## A better solution
|
|
|
|
A better solution would be to use a separate build image to build the binary and then copy it to the final image. As Go generates a standalone binary, we can use the `scratch` docker image as a base which is about as small as it gets!
|
|
|
|
### Dockerfile
|
|
|
|
The following Dockerfile will first build the binary inside the golang image and then build a new image from scratch, copying the binary from the first image into the second.
|
|
|
|
```
|
|
FROM golang:1.11 as build
|
|
|
|
ADD . /app
|
|
|
|
WORKDIR /app
|
|
|
|
RUN go build -o /myserver .
|
|
|
|
|
|
FROM scratch
|
|
|
|
COPY --from=build /myserver /myserver
|
|
|
|
EXPOSE 8080
|
|
|
|
CMD [ "myserver" ]
|
|
```
|
|
|
|
Building from this dockerfile results in a final image size of only 6.55MB! That's over **100 times smaller** than our first attempt, making it 100 times faster to pull the image down from a registry!
|
|
|
|
### Bonus benefit
|
|
|
|
Not only do we now have a tiny docker image for our application, we also only have to worry about the security of our application as there is no other software running inside the container. |