-
Important distinction: Containers are NOT Docker. Docker includes multiple products (i.e. Docker Desktop) and Open Source containerization technologies (i.e. container engine), see Docker's github repo
-
Docker Desktop is recommended because it includes the Docker daemon (dockerd), the Docker client (docker), Docker Compose, Docker Content Trust, Kubernetes, and Credential Helper.
-
Install Docker engine (aka Docker CE) for various Linux Distros here vs. install Docker Desktop for linux here. The Docker Engine is licensed under the Apache License, Version 2.0.
-
How Kubernetes works under the hood with Docker Desktop
-
architecture of docker on mac and how how-docker-for-mac-works-under-the-hood or the-magic-behind-the-scenes-of-docker-desktop and docker-on-macos-is-slow-and-how-to-fix-it
-
Check userland hypervisor qemu here
-
Authenticate to registries
docker login registry.example.comconcretlydocker login -u dejanualex docker.io
-
What is a container here, just a fancy way to run a process
-
After Docker installation, we have the hello world for containers. Using
dockerCLI we can do:
# list all containers from your machine (by all we mean running and also stopped).
# The output should be empty (since there are no containers which have been ran)
docker ps -a
# list all images from your machine.
# The output should be empty (since there are no images pulled on your machine)
docker images
# run your first container.
# The container engine tried to find an image named hello-world, and it did not find it,
# therefore it goes to its default Docker registry, which is Docker Hub, to look for an image named “hello-world
# It finds the image there, pulls it down, and then runs it in a container
docker run hello-world
# rerun commands. What are the changes?
docker ps -a
docker images-
Docker flags (Display system-wide information and Go templates to manipulate the output format)
- Search official images for desired
:
docker search --format "table {{.Name}}\t{{.StarCount}}\t{{.IsOfficial}}" <IMAGE> - Output image name and tag:
docker images --format '{{.Repository}} and {{.Tag}}' - Output image name, tag and elapsed time + timestamp since the image has been created:
docker images --format "{{.Repository}}:{{.Tag}} {{.CreatedSince}} --> {{.CreatedAt}}" - Inspect
Cmdfor desired:
docker inspect -f '{{.Config.Cmd}}' <IMAGE> - Inspect
Entrypointfor desired:
docker inspect -f '{{.Config.Entrypoint}} <IMAGE>' - Inspect attached containers to bridge network:
docker inspect network bridge --format "{{json .Containers }}" - Check root directory for Docker storage, defaults to
/var/lib/docker:docker info -f 'Storage drive: {{.Driver}} and storage path {{.DockerRootDir}}' - Show docker disk usage
docker system df - Inspect container runtimes:
docker system info --format "{{.Runtimes}} {{.DefaultRuntime}}"ordocker system info --format "Runtimes: {{.Runtimes}} with default {{ .DefaultRuntime }}" - Check container resource usage
docker stats [OPTIONS] [CONTAINER], ordocker stats --no-stream - Check events
docker events --filter event=restart --since=60mordocker events --filter event=restart --since=60m > events.log 2>&1
- Search official images for desired
-
Flow: Using a Dockerfile we build a Docker image, and using a Docker image we start/run a container.
flowchart LR;
Dockerfile-->Image;
Image-->Container;
- Debug Docker with systemctl/service and journalctl
systemctl status docker
systemctl daemon-reload
systemctl start docker
service docker restart
journalctl -xeu docker.service
journalctl -u docker
🐳 Optimise your Docker images by 99.4% - not just in size, but in security too!
1️⃣ Use Multi-Stage Builds
Stage 1 compiles your Go binary with all dependencies.
Stage 2 copies only the binary into a minimal base (like distroless or scratch).
💡 Result: up to 99% smaller image with faster CI/CD pipelines.
⸻
2️⃣ Choose Distroless or Scratch Images
Distroless images contain only your app and runtime libs —
no shell, no package manager, no unnecessary tools.
Smaller footprint, fewer CVEs, tighter security.
⸻
3️⃣ Build Static Binaries
Set CGO_ENABLED=0 and use -ldflags="-s -w" to produce static binaries.
They run anywhere — no libc or dynamic dependencies needed.
⸻
4️⃣ Optimise Layer Caching
Order your instructions from least → most changing.
Copy go.mod and go.sum before your source code so dependency layers cache efficiently.
⸻
5️⃣ Never Run as Root
Use a non-privileged user (nonroot:nonroot in distroless).
Even if compromised, impact stays minimal.
⸻
6️⃣ Scan for Vulnerabilities
Use Trivy, Grype, or Docker Scout to catch HIGH and CRITICAL issues before you push.
⸻
✨ Bonus Tip:
Use Dive (wagoodman/dive) to inspect each image layer and see exactly what’s bloating your builds.