Lab 1: The Smallest Website
- Create a folder:
mkdir my-siteand go inside it. - Create
index.html: Write<h1>Hello World</h1>in it. - Create
Dockerfile:DockerfileFROM nginx:alpine COPY index.html /usr/share/nginx/html/index.html - Build:
docker build -t tiny-site:v1 . - Run:
docker run -d -p 9999:80 tiny-site:v1 - Test: Open
http://localhost:9999.
Lab 2: The History Lesson
- Run:
docker history tiny-site:v1 - Observe: Look at the “SIZE” column. You will see the base
nginxlayers are large, and yourCOPYlayer is very small (just bytes). - Learn: This proves that your changes are just a tiny layer on top of the base.
Lab 1: The “Bloatware vs. Slim” Challenge
Goal: See the massive difference a good base image makes.
- Create a folder:
mkdir compare-imagesand go inside. - Create
Dockerfile.fat:DockerfileFROM ubuntu:latest RUN apt-get update && apt-get install -y python3 CMD ["python3", "--version"] - Build Fat Image:
docker build -f Dockerfile.fat -t my-python:fat . - Create
Dockerfile.slim:DockerfileFROM python:alpine CMD ["python", "--version"] - Build Slim Image:
docker build -f Dockerfile.slim -t my-python:slim . - Compare Sizes:
docker images | grep my-python- Result: You will likely see
fatis ~100MB-500MB, whileslimis ~50MB. - Lesson: Always choose specific Alpine or Slim images, not generic OS images like Ubuntu/CentOS.
- Result: You will likely see
Lab 2: Multi-Stage Builds (The Professional Standard)
Goal: Compile code in one container, but ship ONLY the binary in the final image.
- Create a Go file (
main.go): (Even if you don’t know Go, just copy this).Gopackage main import "fmt" func main() { fmt.Println("Hello from a Tiny Container!") } - Create
Dockerfile:Dockerfile# Stage 1: The Builder (Has all the heavy tools) FROM golang:1.21 AS builder WORKDIR /app COPY main.go . RUN go build -o myapp main.go # Stage 2: The Runner (Has almost nothing) FROM alpine:latest WORKDIR /root/ # Copy ONLY the compiled file from the builder stage COPY --from=builder /app/myapp . CMD ["./myapp"] - Build:
docker build -t my-go-app:v1 . - Check Size:
docker images my-go-app:v1- Result: The image will be tiny (maybe 10MB). If you used the standard way, it would be 800MB+!
Lab 3: The Private Registry (Simulating Corporate Environment)
Goal: Run your own “Docker Hub” locally and push images to it.
- Start a Registry:
docker run -d -p 5000:5000 --name local-registry registry:2(You now have a private app store running on port 5000). - Tag an Image for Localhost:
docker tag my-go-app:v1 localhost:5000/my-secret-app:v1 - Push to Local Registry:
docker push localhost:5000/my-secret-app:v1 - Verify: Delete the image from your main list:
docker rmi localhost:5000/my-secret-app:v1Now pull it back:docker pull localhost:5000/my-secret-app:v1 - Cleanup:
docker rm -f local-registry