ABCsteps lesson path

Docker: Make Local Software Repeatable

Understand containers by packaging an app into a repeatable environment that behaves consistently across machines. Build one artifact, keep one review trail, and make the work easy to inspect later.

Lesson
06
Time
45 min
Access
public lesson

Learning objective

Understand what containers solve and how Docker packages an application.

Lab outcome

Write a Dockerfile and run the app in a container.

Module milestone

Containerize and share a working app through a verified deployment path.

Lesson proof workflow

Read, build, then review the evidence.

  1. Docker hero workflow iconStep 1ReadStart with Container basics before touching tools.
  2. Node.js hero workflow iconStep 2BuildBuild toward: Write a Dockerfile and run the app in a container.
  3. JSON hero workflow iconStep 3ReviewReview the evidence using Runtime reproducibility.

Toolchain

Containers make software repeatable across machines.

These are the practical surfaces used in this lesson. Learn the habit first, then connect it to the wider engineering ecosystem.

Docker iconDockerContainers

Package the app and its environment together.

Node.js iconNode.jsRuntime

Run the application inside a predictable container.

JSON iconJSONConfig

Read package and configuration files that shape the build.

Proof of work

Leave one inspectable trail from this lesson.

The useful output is not a passive note. It is a small artifact another person can inspect: a working file, a command result, a commit, a screenshot, a README note, or a demo link.

Lesson lab: Write a Dockerfile and run the app in a container.

Tool and platform logos are ecosystem references only: no affiliation, endorsement, interview access, hiring promise, salary promise, or placement guarantee.

Docker proof icon

Build

Produce the artifact

Complete the lab and keep the result visible: Write a Dockerfile and run the app in a container.

Node.js proof icon

Record

Save review evidence

Capture what changed, what broke, and how Container basics became clearer through the work.

JSON proof icon

Explain

Write the vocabulary

Use your own words for Dockerfile reading and Runtime reproducibility; this is what makes the lesson inspectable later.

Skills companies recognize

Translate the lesson into inspectable work language.

This lesson turns one small lab into the language a learner can use in a README, demo note, or technical conversation. The point is not to collect logos; the point is to explain work clearly enough that another engineer can inspect it.

Where this skill appears

Cloud and backend teams care about repeatability because software must run beyond the learner laptop.

Cloud engineeringBackend servicesDevOps teams

Ecosystem references

AWS skill ecosystem logoGoogle Cloud skill ecosystem logoMicrosoft skill ecosystem logoGitHub skill ecosystem logoCloudflare skill ecosystem logoOpenAI skill ecosystem logoGoogle skill ecosystem logo

Platform and company logos are ecosystem references only: no affiliation, endorsement, interview access, hiring preference, salary outcome, or placement guarantee.

Docker skill proof icon

README line

Name the artifact

Lab proof: Write a Dockerfile and run the app in a container. Connect it to Container basics so the result reads like work, not a passive note.

Node.js skill proof icon

Review line

Explain the stack

Use Docker, Node.js, JSON to explain Dockerfile reading and what changed between the first attempt and the inspected result.

JSON skill proof icon

Conversation line

Answer with evidence

If a team asks about Runtime reproducibility, use this proof line: Show the Dockerfile, the run command, and proof that the same app starts inside the container.

Proof translation

Docker proof translation icon

Skill signal

Container basics is the market word. The lesson makes it visible through a small working artifact.

Node.js proof translation icon

Proof artifact

The inspectable artifact is: Write a Dockerfile and run the app in a container.

JSON proof translation icon

Interview answer

Use Dockerfile reading and Runtime reproducibility to explain what changed, what failed, and how you verified it.

Paid guidance

Read publicly. Upgrade when guidance will help you finish.

This lesson remains part of the public written syllabus. Paid help is online-only and human-led: video walkthroughs as they roll out, live class context, WhatsApp Q&A, and project review around the same work.

No account wall, automated checkout, or placement promise is introduced here. Enrollment stays human-led by WhatsApp or call, and the useful proof remains the learner's own artifact.

Docker paid guidance icon

Public

Written lesson stays open

Read the prepare and review material for lesson 06 on the public site before buying anything.

Node.js paid guidance icon

Recorded

Recorded and live guidance clarify the work

Paid guidance can add founder-led video walkthroughs as they roll out and live online class context; the teaching explains the work, but does not replace the written lesson.

JSON paid guidance icon

Human

Questions use real context

When stuck, useful guidance starts from the route, error, screenshot, repo fragment, and the lab artifact: Write a Dockerfile and run the app in a container.

Phase 1 · Briefing

Lesson briefing

Before You Study (5 mins)

Lesson focus: Why does Netflix work on your TV, your phone, and your laptop exactly the same way? The answer is Docker. It stops the dreaded error: "But it works on MY machine!"

What you should have ready:

  • Docker Desktop installed and running (download from docker.com)
  • Your saved Snake Game from Lesson 01
  • Antigravity open — we'll use AI assistance for the Dockerfile
  • Terminal open in your project folder
  • About 45 minutes of focused time

The Concept

A container is a way to package your application and the exact environment it needs to run, into a single shippable unit. You hand someone a container; they run it; it works the same on their machine as it did on yours. No "but I have a different version of Node" excuses.

People often confuse containers with virtual machines (VMs). They are not the same:

AspectContainerVirtual Machine
What it sharesThe host operating system's kernelNothing — runs its own kernel
Boot timeMillisecondsSeconds to minutes
Size on diskMegabytesGigabytes
IsolationProcess-level (Linux features)Hardware-level (a hypervisor)
Density on one hostHundredsTens

The reason a container can boot in milliseconds is that it's not booting an OS. It's just starting a process inside an isolated view of the existing kernel. Three Linux features make this possible:

  • Namespaces — control what a process can see (its own PID 1, its own network interfaces, its own filesystem tree)
  • cgroups — control what a process can use (CPU time, memory, disk I/O limits)
  • Union filesystems — let images be built up in layers, with each layer reused across many containers

Docker is a friendly UX wrapper around these three kernel features. When you run docker run nginx, Docker asks the Linux kernel to create a new set of namespaces and cgroups, mounts a layered filesystem, and starts the nginx process inside that isolated environment.

Want the deep dive? This lesson keeps the concept short. The companion article How Docker Actually Works — Container Internals Explained walks through namespaces, cgroups, and OverlayFS with real /proc and /sys/fs/cgroup paths you can verify yourself.

The other word you'll hear constantly is image. An image is a template — a packaged filesystem snapshot, in layers, that contains your app and its dependencies. A container is a running instance of an image. One image, many containers. Like one class definition and many instances.

Layers and the build cache

The reason docker build runs fast on subsequent builds is the layer cache. Each instruction in a Dockerfile produces one layer:

dockerfile
FROM node:20-alpine                  # layer 1: base image (~50MB)
WORKDIR /app                         # layer 2: filesystem change
COPY package*.json ./                # layer 3: dependency manifests
RUN npm ci --production              # layer 4: installed node_modules
COPY . .                             # layer 5: your source code
EXPOSE 3000                          # layer 6: metadata only
CMD ["node", "server.js"]            # layer 7: default command

Docker caches each layer by content. The next time you build, if package.json hasn't changed, layers 1-4 reuse the cache and only layer 5 (your code) rebuilds. A clean rebuild that would take 90 seconds drops to 5. The Dockerfile instruction order matters — putting COPY . . before npm ci would invalidate the cache on every code change. Always copy dependency manifests, install, and only then copy source.

This is the single biggest practical lesson hiding inside "Docker": the build cache is your friend if you order instructions from least-frequently-changing to most-frequently-changing.

Why containers won

Before Docker (2013), shipping software meant either:

  • "Here is a tar.gz. Good luck installing 47 dependencies in the right order."
  • "Here is a 4GB virtual machine image. Allocate 8GB of RAM and pray your laptop survives."

Containers replaced both. A 50MB image starts in milliseconds, runs anywhere with a Linux kernel (Mac, Windows via WSL, every cloud), and packages exactly what your app needs. Netflix, Spotify, Stripe, every company that ships software at scale today runs on containers. The pattern is universal because the problem it solves — "will my code run somewhere other than my laptop" — is universal.

Quick Concepts

TermSimple Meaning
ContainerA "Magic Lunchbox" that keeps your app fresh anywhere
ImageThe recipe for the lunchbox (what goes inside, in what order)
DockerfileThe instruction sheet that builds the recipe
PortA specific door on your computer (3000, 8080) where traffic enters
LayerOne step of the recipe — reused across many containers

What We Will Build

By the end of this lesson, you will have done these specific things:

  1. Verified Docker Desktop is running by typing docker --version in the terminal.
  2. Opened your Snake Game project folder.
  3. Asked Antigravity to write a Dockerfile for a simple Node.js or static-HTML project, and inspected it line by line.
  4. Built the image with docker build -t snake-game . (note the trailing dot).
  5. Run the container with docker run -p 3000:3000 snake-game.
  6. Loaded http://localhost:3000 in your browser and confirmed your game runs inside the container.
  7. Stopped the container and inspected the image with docker images and docker history.

When you finish, you will have shipped your first container. Not metaphorically — actually.

Common Pitfalls

These are the four mistakes most people make in their first Docker build, in roughly the order they hit:

  1. "Port already in use" — you ran the container, then ran it again without stopping the first. Both want port 3000. Fix: docker ps to see what's running, docker stop <id> to stop it. Or use a different host port: docker run -p 3001:3000 snake-game.
  2. "My changes aren't showing up" — you edited a source file but the container is still serving the old code. The image was built from the old code; the container runs that frozen image. Fix: rebuild (docker build -t snake-game .) or use a volume mount in development (-v $(pwd):/app). The first is correct for shipping; the second is correct for iterating.
  3. Image is 1.5GB — you used node:20 (full Debian) instead of node:20-alpine (small Linux variant). Or you COPY . before .dockerignore was set up, so node_modules and .git got baked in. Fix: prefer slim/alpine base images, write a .dockerignore that excludes node_modules, .git, .env, and other local-only files.
  4. "docker: command not found" — Docker Desktop isn't running on your Mac/Windows machine. The docker CLI talks to the Docker daemon; if the daemon isn't running, the CLI returns this error. Fix: open Docker Desktop and wait for the whale icon to settle.

If you hit a pitfall not on this list, the fix is almost always in docker logs <container-id> — the container's stdout/stderr is the first place to look.

Think About

Before studying, consider:

  1. Have you ever sent a file to a friend and they couldn't open it because they "didn't have the right font"? Now imagine your whole app is the file, and the font is Node version 20.11 with these 47 npm packages and this exact Linux distribution. That's the problem Docker solves.
  2. If a container only takes milliseconds to start, what could you do with that speed that you couldn't do with virtual machines? (Hint: think about how Netflix handles a sudden traffic spike.)
  3. Why does the order of instructions in a Dockerfile matter? What would go wrong if you put COPY . . before RUN npm ci?

By the End

After this lesson, you'll:

  • ✅ Understand what containers actually are at the kernel level
  • ✅ Have written your first Dockerfile (with AI assistance, but you'll read every line)
  • ✅ Have built your first image and run your first container
  • ✅ Be able to explain the difference between an image and a container
  • ✅ Know where to read more when you want to go deeper (the companion blog post)

Let's package your app. 📦

Next lesson · 07

Cloudflare Tunnel: Share a Local App Safely

Learn what a tunnel is, when it is useful, and how Cloudflare can expose a local app for demos without pretending it is full production hosting.

Cloudflare next lesson iconNode.js next lesson iconGit next lesson icon