Optimizing Images
Use lighter Base Images
Opt for using alpine
based versions of base images, since they are lighter and more tightly controlled versions.
Label you Dockerfile
Use Label
s to help organize Images. Like:
LABEL com.example.version="1.0.0-beta"
LABEL com.example.release-date="2024-04-04"
Pinning Image tag versions
Even if you select images by a tag version, it is not garanteed that rebuilding the Image some time later will result in the same Image being made. (Since updates by a publisher on a version tag will change it)
FROM image:3.20
To avoid that and always get the same Image no matter what, pin the image version to a specific digest.
FROM image:3.20@sha256:13b7e62e8df80264dbb747995705a986aa530415763a6c58f84a3ca8af9a5bcd
This way, even if the publisher updates the Image with tag version 3.20
, you are still pinned to the specific digest 13b7e62e8df80264dbb747995705a986aa530415763a6c58f84a3ca8af9a5bcd
.
Doing this may lock you out of security updates, done by the publisher in their Images.
Use BuildKit
instead of Legacy Builder
BuildKit
instead of Legacy Builder
The Legacy Docker Engine builder processes all stages of a Dockerfile. It will build a stage even if the selected target doesn't depend on that stage.
BuildKit
only builds stages that the target depend on.
Exclude with .dockerignore
.dockerignore
To exclude files not relevant to the build, without restructuring your source repository, use a .dockerignore
file.
Create disposable containers
Create containers that if stopped and destroyed, can easily be recreated with minium setup and configuration.
Decoupled applications
Containers should have only one concern. (Single responsability)
It is when you use multiple FROM
instructions in the Dockerfile. Each one can use a different base image, and each one begins a new stage of the build.
The ideia is to then selectively copy artifacts from one stage to another, leaving behind everything you don't want in the final image. (Like temporary files)
FROM golang:1.23
WORKDIR /src
COPY ./main.go .
RUN go build -o /bin/hello ./main.go
FROM scratch
# You could name the stage if you want
# Otherwise refer to them using their index number (starting from 0)
COPY --from=0 /bin/hello /bin/hello
CMD ["/bin/hello"]
In the final Image, only the binary is copied, so none of the required tools to compile are needed in the final image.
Naming Build Stages
FROM <image> AS <name>
FROM golang:1.23 AS build
WORKDIR /src
COPY ./main.go .
RUN go build -o /bin/hello ./main.go
FROM scratch
COPY --from=build /bin/hello /bin/hello
CMD ["/bin/hello"]
Picking stages when building
docker build --target build -t "your-image-name" .
Using previous stage in FROM
FROM
FROM alpine:latest as build
...
FROM build AS optBuild
...
Last updated