All Modules Why Docker Concepts Hands-on Lab Cheat Sheet

Docker for Beginners

Package any app into a container that runs the same everywhere.

Module 6 · The "aha!" moment of DevOps. Free · No cloud account needed.

Beginner Containers ~45 min

What You'll Learn

By the end of this module you will be able to:

  • Explain what a container is and the problem it solves (in plain English)
  • Tell the difference between an image, a container, and a registry
  • Install Docker and verify it works
  • Write a Dockerfile for a real web app
  • Build an image, run it as a container, and open it in your browser
  • Push your image to Docker Hub so anyone can run it

Prerequisites: A terminal and basic command-line comfort (Modules 2–3). No prior Docker knowledge.

Why Docker Exists

You finish an app on your laptop. It works perfectly. You send it to a teammate — and it breaks. Different Python version, a missing library, the wrong operating system. This is the famous:

"But it works on my machine!"

The root cause: your app depends on its environment (OS, runtime, libraries, config) — and that environment is different on every machine.

A container solves this by packaging your app together with everything it needs to run into one sealed box. That box runs identically on your laptop, your teammate's, a test server, and production.

The shipping-container analogy

Before shipping containers, cargo was loaded loose — slow, and every ship handled it differently. The steel container standardized everything: any crane, any ship, any truck handles the same box. Docker does this for software: your app, standardized into a box that any machine with Docker can run.

Container vs. Virtual Machine

A VM virtualizes a whole computer (its own OS) — gigabytes in size, slow to boot. A container shares the host's OS kernel and only packages your app + its dependencies — megabytes in size, starts in milliseconds. That lightness is why containers won.

The 3 Words You Must Know

Almost all of Docker comes down to three ideas. Get these and everything else clicks.

TermWhat it isAnalogy
ImageA read-only template: your app + dependencies, frozen. Built once, never changes.A class, or a cookie cutter
ContainerA running instance of an image. You can start many from one image.An object, or the cookie
RegistryAn online store for images (e.g. Docker Hub). You push to share and pull to download.GitHub, but for images

The lifecycle in one line

Dockerfile  →  docker build  →  Image  →  docker run  →  Container  →  docker push  →  Registry

A Dockerfile is the recipe — a plain text file of instructions for building an image. You'll write one in the lab.

Install Docker

Install Docker Desktop (free for personal use, learning, and small businesses). It bundles everything you need on Mac, Windows, and Linux.

Download

Get it from docker.com/products/docker-desktop. On Windows, accept the WSL 2 prompt if asked. Then launch the app once so the engine starts.

Verify it's working — open your terminal and run:

docker --version docker run hello-world

If you see "Hello from Docker!", Docker pulled a tiny image from the registry, ran it as a container, and it printed a message — you just ran your first container. 🎉

Common first error

Cannot connect to the Docker daemon means the engine isn't running. Open the Docker Desktop app and wait for the whale icon to say "Engine running," then retry.

Hands-on Lab: Containerize a Web App

We'll containerize a tiny Python Flask web app — the same sample app we reuse through the whole course. Follow along; every command is copy-paste.

Prefer not to type it all?

You can download the complete starter project (every file used across the course). But typing it out the first time is the best way to learn — we recommend following along.

1

Create the project folder

mkdir notes-app cd notes-app
2

Write the app — app.py

A minimal web server that returns a page. Create a file called app.py:

from flask import Flask import os app = Flask(__name__) @app.route("/") def home(): return "<h1>Hello from inside a container! 🐳</h1>" if __name__ == "__main__": port = int(os.environ.get("PORT", 5000)) app.run(host="0.0.0.0", port=port)

Why host="0.0.0.0"?

Inside a container, 127.0.0.1 means "only this container." Binding to 0.0.0.0 lets traffic from your host machine reach the app. Forgetting this is the #1 reason a containerized web app "won't load."

3

List dependencies — requirements.txt

flask==3.0.3
4

Write the recipe — Dockerfile

Create a file named exactly Dockerfile (no extension). We explain every line in the next section.

FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 5000 CMD ["python", "app.py"]
5

(Recommended) Add a .dockerignore

Keeps junk out of your image and speeds up builds:

__pycache__/ *.pyc .git .env venv/
6

Build the image

The -t flag tags (names) your image. The . means "build using this folder."

docker build -t notes-app .

Confirm it exists:

docker images
7

Run the container

-p 8080:5000 maps port 8080 on your machine to port 5000 inside the container. -d runs it in the background; --name gives it a friendly name.

docker run -d -p 8080:5000 --name notes notes-app

Now open http://localhost:8080 in your browser. You should see the whale greeting — served from inside your container. ✅

The "aha!" moment

Your app is now running with zero Python or Flask installed directly on your machine — everything lives in the container. Delete the container and your system is spotless.

8

Inspect & clean up

docker ps # see running containers docker logs notes # view its output docker stop notes # stop it docker rm notes # delete the container
9

(Optional) Share it on Docker Hub

Create a free account at hub.docker.com, then:

docker login docker tag notes-app YOUR_USERNAME/notes-app:1.0 docker push YOUR_USERNAME/notes-app:1.0

Anyone, anywhere, can now run your exact app with one command: docker run -p 8080:5000 YOUR_USERNAME/notes-app:1.0. That is the power of Docker.

The Dockerfile, Line by Line

Each instruction adds a layer to your image. Understanding them is the core skill of this module.

InstructionWhat it does
FROM python:3.12-slimStart from an official, slim Python base image. You never build from scratch.
WORKDIR /appSet the working directory inside the container. Later commands run here.
COPY requirements.txt .Copy just the deps file first — so the next (slow) step is cached.
RUN pip install ...Install dependencies during the build, baking them into the image.
COPY . .Copy the rest of your code into the image.
EXPOSE 5000Document which port the app listens on (informational).
CMD ["python","app.py"]The command that runs when the container starts.

Why copy requirements.txt before the code?

Docker caches each layer. If you change only your code (not your dependencies), Docker reuses the cached pip install layer — rebuilds drop from minutes to seconds. This ordering trick is the most important Dockerfile optimization for beginners to learn.

Command Cheat Sheet

The 90% of Docker commands you'll actually use day to day. Bookmark this.

CommandWhat it does
docker build -t name .Build an image from the Dockerfile in this folder
docker imagesList images on your machine
docker run -d -p 8080:5000 nameRun a container in the background, map ports
docker psList running containers
docker ps -aList all containers (incl. stopped)
docker logs <name>Show a container's output
docker exec -it <name> bashOpen a shell inside a running container
docker stop <name>Stop a running container
docker rm <name>Delete a (stopped) container
docker rmi <image>Delete an image
docker pull <image>Download an image from a registry
docker push <image>Upload your image to a registry
docker system pruneClean up unused containers, images, networks

Troubleshooting

SymptomLikely cause & fix
Cannot connect to the Docker daemonDocker Desktop isn't running — open the app and wait for "Engine running."
Page won't load in browserApp bound to 127.0.0.1 instead of 0.0.0.0, or wrong -p mapping.
port is already allocatedAnother process uses 8080 — change the host port, e.g. -p 8081:5000.
Container exits immediatelyApp crashed on start — run docker logs <name> to see the error.
Code change not showingYou must docker build again — images are snapshots, not live.
"name is already in use"A container with that name exists — docker rm <name> first.

Your Challenge

Cement it by doing. Try these before moving on:

  • Add a second route /about that returns your name, rebuild, and run it.
  • Run the container on port 9000 instead of 8080.
  • Use docker exec -it notes bash to look around inside the container, then exit.
  • Bonus: push your image to Docker Hub and send a friend the one-line run command.
@app.route("/about") def about(): return "<h1>Built by [your name] 🚀</h1>" # then: docker build -t notes-app . && docker run -d -p 8080:5000 --name notes notes-app

Recap & What's Next

You can now

Explain containers, write a Dockerfile, build an image, run it, and share it. That's the foundation everything else in DevOps builds on.

Next up: Module 7 — Docker Compose, where you'll run your app and a database together with a single command.

Docker for Beginners

Objectives Why Docker 3 Key Concepts Install Hands-on Lab Dockerfile Explained Cheat Sheet Troubleshooting Challenge Recap