= 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]
--
---
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]
--
* reduce build time by layer cache

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]
--
* reduce layer numbers

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]
--
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]
--
* remove all not needed files

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]
--
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[]
----

== 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
