DevOps Foundations · Module 5: Container basics · Lab
Build a Reproducible Non-root Image for a Small Service
45 min hands-on · Core
Local Docker or Podman; a small service (static site, tiny API) under /tmp/dlab-m05-01.
Two ways to do this lab: in your browser on Killercoda (free, no install), or on your own machine as a local guide. Killercoda runs one free scenario at a time: if you see a waiting queue, close other Killercoda tabs and wait a minute.
Objectives
- Write a multi-stage Dockerfile with cached layers and pinned bases
- Run the result as a numeric non-root user with proof
- Show before/after size and no-change rebuild time
Step 1
Ship the naive image first
Build a single-stage image as root with unpinned base and app copied before dependencies. Record image size and a full rebuild time.
Step 2
Rebuild it properly
Convert to multi-stage with pinned base, dependency-first layer order, .dockerignore, USER 10001 with owned writable paths. Rebuild and record size plus no-change rebuild time.
Step 3
Prove non-root and repeatability
Run as the numeric user, write to the app's writable path, and show id -u output from inside. Rebuild twice from clean cache state and show identical image digests.
How to confirm it worked
- Naive baseline size and time recorded before the repair
- Final image smaller with pinned bases and multi-stage history
- Runtime UID is non-root, shown from inside the container
- Two clean rebuilds produce the same digest