You will write a Dockerfile, build it with multi-stage layers, and scan the result for vulnerabilities. By the end you will produce a small, cache-friendly image with a minimal attack surface.

Learning Objectives

  • Author a Dockerfile using layer-cache-friendly ordering.
  • Shrink images with a multi-stage build.
  • Scan images for known CVEs with Trivy.
  • Time: ~3 hours · Difficulty: Intermediate · Prereqs: Docker and a small app to containerize.

Architecture Overview

Environment Setup

You will need: Docker with BuildKit and Trivy (install docs).

Before you begin: have a buildable app (a small Go or Node service works well).

Step-by-Step Execution

01
Write a multi-stage Dockerfile

Compiling in a build stage and copying only the artifact into a slim base keeps the runtime tiny.

# Dockerfile
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o app .

FROM gcr.io/distroless/static
COPY --from=build /src/app /app
ENTRYPOINT ["/app"]
02
Build with cache and a tag
DOCKER_BUILDKIT=1 docker build -t tyf/app:1.0 .
BuildKit caches layers, speeding up rebuilds.
03
Compare image size
$ docker images tyf/app
REPOSITORY TAG SIZE tyf/app 1.0 12.3MB <- distroless runtime
04
Scan for vulnerabilities
trivy image --severity HIGH,CRITICAL tyf/app:1.0

Progress So Far

Testing & Validation

docker run --rm tyf/app:1.0 --version && trivy image --exit-code 1 --severity CRITICAL tyf/app:1.0

The app should run and Trivy should exit 0 (no criticals). If so, you have a small, scanned image.

Troubleshooting
  • Image still huge: ensure the final stage uses a slim/distroless base and copies only the artifact.
  • Cache never hits: order Dockerfile steps from least to most frequently changing.
  • Trivy DB error: run with internet access on first use to fetch the vulnerability DB.

Extension Ideas

Key Results

  • Produced a ~12MB runtime image via multi-stage build.
  • Cut rebuild time with BuildKit layer caching.
  • Scanned for HIGH/CRITICAL CVEs before shipping.
  • Minimized attack surface with a distroless base.