diff --git a/docker-training/CLAUDE.md b/docker-training/CLAUDE.md index 1f870ba..bc1bd32 100644 --- a/docker-training/CLAUDE.md +++ b/docker-training/CLAUDE.md @@ -19,15 +19,16 @@ Sections are loaded in this order (see `index.html`): 9. `docker-desktop.html` — Docker Desktop 10. `docker-commands.html` — CLI commands 11. `docker-images.html` — images & Dockerfiles -12. `docker-networking.html` — container networking -13. `docker-volumes.html` — persistent storage -14. `docker-compose.html` — Docker Compose -15. `devops-docker.html` — DevOps with Docker -16. `docker-swarm.html` — Swarm orchestration -17. `serverless.html` — serverless concepts -18. `docker-kubernetes.html` — Kubernetes overview -19. `monitoring.html` — container monitoring -20. `resources.html` — further resources +12. `multistage-builds.html` — multi-stage builds +13. `docker-networking.html` — container networking +14. `docker-volumes.html` — persistent storage +15. `docker-compose.html` — Docker Compose +16. `devops-docker.html` — DevOps with Docker +17. `docker-swarm.html` — Swarm orchestration +18. `serverless.html` — serverless concepts +19. `docker-kubernetes.html` — Kubernetes overview +20. `monitoring.html` — container monitoring +21. `resources.html` — further resources ## Local Development diff --git a/docker-training/index.html b/docker-training/index.html index 3291026..d7f69fe 100644 --- a/docker-training/index.html +++ b/docker-training/index.html @@ -40,6 +40,7 @@
+
diff --git a/docker-training/sections/multistage-builds.html b/docker-training/sections/multistage-builds.html new file mode 100644 index 0000000..ef5e9e8 --- /dev/null +++ b/docker-training/sections/multistage-builds.html @@ -0,0 +1,142 @@ +

Multi-Stage Builds

+ +
+

The Problem — Bloated Images

+
+
+

+FROM golang:1.23
+
+WORKDIR /app
+COPY main.go .
+RUN go build -o hello main.go
+
+EXPOSE 8080
+CMD ["./hello"]
+      
+

+$ docker image ls hello-single
+REPOSITORY     SIZE
+hello-single   838 MB
+      
+
+
+
+ +

Compiler & build tools ship in the final image — never needed at runtime.

+
+
+ +

More packages = more vulnerabilities, slower pulls, higher costs.

+
+
+
+
+ +
+

Multi-Stage Builds

+
+
+

+# Stage 1: Build
+FROM golang:1.23 AS builder
+WORKDIR /app
+COPY main.go .
+RUN CGO_ENABLED=0 go build -o hello main.go
+
+# Stage 2: Minimal runtime
+FROM alpine:3.21
+WORKDIR /app
+COPY --from=builder /app/hello .
+EXPOSE 8080
+CMD ["./hello"]
+      
+
+ +
+
+ +
+

The Result — 98% Smaller

+
+
+ +

Single-Stage

+

Go toolchain + compiler + sources + app

+

+hello-single   838 MB
+      
+
+
+ +

Multi-Stage

+

Alpine Linux + compiled binary only

+

+hello-multi    12.1 MB
+      
+
+
+
+ +
+

Named Stages & COPY --from

+
+
+

Assign names with AS

+

+FROM golang:1.23 AS builder
+FROM alpine:3.21 AS runtime
+      
+

Reference by name or number

+

+# By name (preferred)
+COPY --from=builder /app/hello .
+
+# From an external image
+COPY --from=nginx:latest \
+  /etc/nginx/nginx.conf /nginx.conf
+      
+
+
+ +

Copy from any build stage or external image — without including it in the final result.

+
+
+
+ +
+

One Dockerfile, Multiple Targets

+
+
+

+# Production: run all stages
+$ docker image build \
+  --tag hello-multi:1.0 .
+
+# Dev: stop at the builder stage
+$ docker image build \
+  --target builder \
+  --tag hello-dev:1.0 .
+      
+

+REPOSITORY   SIZE
+hello-multi  12.1 MB   # production
+hello-dev    838 MB    # full toolchain
+      
+
+
+
+ +

Production — minimal image, binary only.

+
+
+ +

Development — full toolchain, same Dockerfile.

+
+
+
+