Photo by Fabian Grohs on Unsplash
So, you have read of the scratch
Docker image and tried out a docker pull scratch
, which failed.
What happened?
And why?
Let me explain.
scratch
is not a real Docker image.
It is a reserved keyword in the Docker space that basically means "start with empty filesystem".
FROM scratch
won't even count as a new layer.
It is a no-op in Dockerfile
s.
Imagine you have a binary called hello
.
If you want a Docker container that just starts that binary you can create a basic Docker file like this:
FROM scratch
COPY hello /
CMD ["/hello"]
This will create a one-layer image with only the COPY
command.
If we look into the scratch
documentation we find:
You can use Docker’s reserved, minimal image,
scratch
, as a starting point for building containers. Using thescratch
“image” signals to the build process that you want the next command in theDockerfile
to be the first filesystem layer in your image.While
scratch
appears in Docker’s repository on the hub, you can’t pull it, run it, or tag any image with the namescratch
. Instead, you can refer to it in yourDockerfile
.
This is extremely useful if you work with compiled languages like Go. You'll get the smallest possible Docker image with a multi-staged build file:
FROM golang:alpine AS builder
RUN apk update && apk add --no-cache git
WORKDIR $GOPATH/src/mypackage/myapp/
COPY . .
RUN go get -d -v
RUN GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/app
FROM scratch
COPY --from=builder /go/bin/app /go/bin/app
CMD ["/go/bin/app"]
(Thanks to @chemidy)