Let’s start by creating a Dockerfile:
FROM golang:1.20.5 AS build
WORKDIR /tmp
COPY app.go .
RUN GO111MODULE=off GOOS=linux go build -a -installsuffix cgo -o app . && chmod +x ./app
FROM gcr.io/distroless/base
WORKDIR /tmp
COPY –from=build /tmp/app .
CMD [“./app”]
This Dockerfile is similar to the multi-stage build Dockerfile for thego-hello-world container, but instead of using alpine, it uses gcr.io/distroless/base as the base image. This image contains a minimalistic Linux glibc-enabled system and lacks a package manager or a shell. You can use it to run binaries compiled in a language such as Go, Rust, or D.
So, let’s build this first using the following command:
$ docker build -t <your_dockerhub_user>/go-hello-world:distroless .
[+] Building 7.6s (14/14) FINISHED
=> [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 268B 0.0s => [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for gcr.io/distroless/base:latest 3.1s => [internal] load metadata for docker.io/library/golang:1.20.5 1.4s => [auth] library/golang:pull token for registry-1.docker.io 0.0s => [stage-1 1/3] FROM gcr.io/distroless/base@ sha256:73deaaf6a207c1a33850257ba74e0f196bc418636cada9943a03d7abea980d6d 3.2s => [build 1/4] FROM docker.io/library/golang:1.20.5@sha256:4b1fc02d 0.0s => [internal] load build context 0.0s
=> => transferring context: 108B 0.0s
=> CACHED [build 2/4] WORKDIR /tmp 0.0s
=> CACHED [build 3/4] COPY app.go . 0.0s
=> CACHED [build 4/4] RUN GO111MODULE=off GOOS=linux go build -a -installsuffix cgo -o app . && chmod +x ./app 0.0s
=> [stage-1 2/3] WORKDIR /tmp 0.9s
=> [stage-1 3/3] COPY –from=build /tmp/app . 0.3s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:51ced401 0.0s
=> => naming to docker.io/<your_dockerhub_user>/go-hello-world:distroless
Now, let’s run this image and see what we get:
$ docker run <your_dockerhub_user>/go-hello-world:distroless Hello, World!
It works! Let’s look at the size of the image:
$ docker images
REPOSITORY
<your_dockerhub_user>/go-hello-world
TAG
distroless
MAGE ID 51ced401d7bf
CREATED
6 minutes ago
SIZE
22.3MB
It’s just 22.3 MB. Yes, it’s a bit more than the Alpine image, but it does not contain a shell, so it is more secure from that point of view. Also, there are distroless images available for interpreted programming languages, such as Python and Java, that you can use instead of the bloated image containing the toolkits
Docker images are stored in Docker registries, and we have all been using Docker Hub for a while.
In the next section, we’ll understand what they are and what our options are for storing our images.