= Docker Build Optimization :source-highlighter: highlightjs == Why Optimize Docker Builds? * Faster build times * Reduced image size == Optimization Strategies * Reordering * Combining * Mounting and local Cache * Multi-stage builds * Choose of base image * Clean docker build context * Remote Caching == Demo === Base Image [source,docker] ---- include::../.docker-files/0-origin.Dockerfile[] ---- [.notes] -- * showcase before applying any optimization strategies. docker build -f .docker-files/0-origin.Dockerfile -t demo/base . docker build -f .docker-files/0-origin.Dockerfile -t demo/base . touch foo docker build -f .docker-files/0-origin.Dockerfile -t demo/base . dive demo/base -- === Reordering [source,docker] ---- include::../.docker-files/1-reordering.Dockerfile[] ---- [.notes] -- * significantly optimize build times by utilizing layer caching efficiently. docker build -f .docker-files/1-reordering.Dockerfile -t demo/reorder . docker build -f .docker-files/1-reordering.Dockerfile -t demo/reorder . touch bar docker build -f .docker-files/1-reordering.Dockerfile -t demo/reorder . dive demo/reorder -- === Combining [source,docker] ---- include::../.docker-files/2-combining.Dockerfile[] ---- [.notes] -- * Combining multiple commands into a single RUN instruction reduces the number of image layers. * fewer layers improve performance and efficiency. docker build -f .docker-files/2-combining.Dockerfile -t demo/combine . dive demo/combine -- === Mounting and local Cache [source,docker] ---- include::../.docker-files/3-mounting.Dockerfile[] ---- [.notes] -- * mounting and local caching optimize e.g. package installations during builds. docker build -f .docker-files/3-mounting.Dockerfile -t demo/mounts . * extend intall package list docker build -f .docker-files/3-mounting.Dockerfile -t demo/mounts-2 . dive demo/mounts -- === Multi-stage builds [source,docker] ---- include::../.docker-files/4-multi-stage.Dockerfile[] ---- [.notes] -- * create smaller images by separating the build environment from the final application image. docker build -f .docker-files/4-multi-stage.Dockerfile -t demo/multistage . dive demo/multistage -- === Choose of base image [source,docker] ---- include::../.docker-files/5-base-image.Dockerfile[] ---- [.notes] -- * base image can significantly impact the final image size and functionality. docker build -f .docker-files/5-base-image.Dockerfile -t demo/alpine . dive demo/alpine -- === Using pinned image [source,docker] ---- include::../.docker-files/6-pinimage.Dockerfile[] ---- [.notes] -- * Pinning versions of the base image and dependencies ensures consistency and reproducibility. -- == Clean docker build context * The `.dockerignore` file excludes unnecessary files from the build context [source,plaintext] ``` .git .gitignore .dockerignore *.log tmp/* ``` == Remote Caching * other build driver like https://docs.docker.com/build/drivers/[`docker-container`^] supports cache export [source,shell] ---- docker buildx build \ --cache-from myapp:cache \ --cache-to myapp:cache \ -t myapp:latest \ . ---- * Kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster. [source,shell] ---- kaniko build --cache=true -f Dockerfile. ---- [.notes] -- * It's designed to work without Docker daemon * making it suitable for environments with restricted access. -- == Resources * Docker Documentation: https://docs.docker.com/ * Docker Build Best Practices: ** https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ ** https://docs.docker.com/build/cache/ * .dockerignore Documentation: https://docs.docker.com/engine/reference/builder/#dockerignore-file * Remote Caching with Buildx: https://docs.docker.com/build/cache/backends/ * Kaniko GitHub Repository: https://github.com/GoogleContainerTools/kaniko * Alpine Linux: https://alpinelinux.org/ * Dive - A tool for exploring each layer in a Docker image: https://github.com/wagoodman/dive