By the end of this module, students will:
This foundational knowledge will support the first practical project: Containerizing and running a simple web application using Docker, suitable for publishing to GitHub or Docker Hub.
Docker is an open-source platform that simplifies how developers build, ship, and run applications. It uses a technology called containerization, which packages applications and all their dependencies into a single, portable unit called a container.
This means that your application can run anywhere — on your laptop, in the cloud, on a production server — without worrying about environment mismatches or missing libraries.
A container is a lightweight, standalone, executable software package that includes:
Unlike virtual machines, containers share the host system’s kernel and do not require a full operating system per instance — making them much faster and more efficient.
Think of containers like shipping containers in logistics. Regardless of what’s inside (cars, clothes, electronics), every container has the same standard size and can be loaded on ships, trucks, or trains. Similarly, Docker containers ensure your software runs the same no matter the environment.
Feature | Containers | Virtual Machines |
---|---|---|
Startup Time | Seconds | Minutes |
Resource Usage | Low | High (entire OS) |
Isolation Level | Process-level isolation | Full OS isolation |
Portability | High | Moderate (OS-specific) |
Use Case | Microservices, CI/CD | Full OS environments |
Before Docker and containerization became widespread, the most common way to isolate applications was through virtual machines (VMs). Both VMs and containers are used to create isolated environments for applications, but they differ significantly in how they achieve that isolation.
A virtual machine emulates an entire physical computer, including:
VMs run on top of a hypervisor like VMware, VirtualBox, or KVM, which manages multiple guest OSes on a single physical machine.
Docker containers take a different approach. Instead of emulating full machines, containers:
This makes them much faster, lighter, and easier to manage than VMs.
Feature | Virtual Machines (VMs) | Docker Containers |
---|---|---|
Startup Time | Minutes (boot full OS) | Seconds (start process) |
Guest OS | Required per VM | Not needed (shared kernel) |
Image Size | Large (GBs) | Small (MBs) |
Performance | Overhead from hypervisor and guest OS | Near-native speed |
Isolation | Strong – full system isolation | Process-level (less overhead) |
Security Surface | Larger (full OS, attack surface) | Smaller but depends on host kernel security |
Portability | Limited by hypervisor or OS | High – run anywhere Docker is supported |
Management | Complex – multiple OSes to update | Simple – containers run on same OS |
Use Case | Better Fit |
---|---|
Running multiple OS types (e.g., Windows + Linux) | Virtual Machines |
Strong multi-tenant security (full isolation) | Virtual Machines |
Lightweight, fast deployment | Docker |
CI/CD pipelines or dev environments | Docker |
Legacy apps with OS dependencies | VMs (initially) or Docker with care |
Both VMs and containers serve different purposes. Containers don’t replace VMs — they complement them. In modern infrastructures, you often see containers running inside virtual machines for the best of both worlds: security from VMs and agility from containers.
Understanding these core concepts is essential before working with Docker in real-world scenarios. These elements form the foundation of Docker’s architecture.
A Docker image is a read-only, immutable file that serves as a blueprint for a container. It contains:
Images are built in layers. Each command in a Dockerfile
(like RUN
, COPY
, ADD
) creates a new image layer, which makes them efficient to reuse and share.
Analogy: Think of an image like a cake recipe. It doesn’t do anything by itself, but it tells Docker how to build a working app (container).
Example:
docker pull nginx
This downloads the official nginx
image from Docker Hub.
A container is a runtime instance of an image. When you start a container from an image:
Analogy: If an image is a recipe, a container is a cake made using that recipe. You can make multiple cakes (containers) from the same recipe (image).
Example:
docker run -d -p 80:80 nginx
This runs a container from the nginx
image in the background (-d
), exposing port 80.
Containers are ephemeral by default – when stopped, changes are lost unless you use volumes (see below).
A Dockerfile is a plain text file that contains step-by-step instructions for building a Docker image. It allows you to automate the setup of:
Typical instructions include: FROM
, COPY
, RUN
, CMD
, EXPOSE
.
Example Dockerfile:
FROM python:3.11
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "main.py"]
Once you have a Dockerfile, you can build the image with:
docker build -t my-python-app .
The Docker Engine is the software that makes Docker work. It consists of three main components:
dockerd
) docker
) docker run
, docker build
, etc.Example interaction:
docker ps
This sends a request from the CLI to the daemon to list running containers.
Docker Hub is a cloud-based registry service where users can:
ubuntu
, nginx
, postgres
)Official images are maintained by Docker and trusted by the community.
Example:
docker pull node:20
This pulls the official Node.js image (version 20).
You can also push your own image to Docker Hub:
docker tag my-app your-username/my-app
docker push your-username/my-app
A volume is a Docker-managed directory on the host machine used to persist data outside the container’s writable layer.
Why it matters:
You’ll learn more in Module 4, but it’s important to know containers without volumes = temporary data only.
Example:
docker run -v myvolume:/data busybox
Concept | Description |
---|---|
Image | Blueprint with app code and dependencies |
Container | Running instance of an image |
Dockerfile | Script to build custom images |
Docker Engine | Software to run/build/manage containers |
Docker Hub | Cloud registry for public/private images |
Volume | Persistent storage across container restarts |
Docker uses a client-server architecture that enables developers to build, run, and manage containers efficiently. Understanding the core components and how they interact is essential before diving deeper into practical usage.
The Docker Client is what you interact with — typically through the command line interface (CLI). When you run commands like docker build
, docker run
, or docker ps
, the client sends those commands to the Docker Daemon via REST API.
Analogy: Think of the client as a remote control — it tells Docker what to do, but doesn’t do the work itself.
docker pull nginx
This command tells the daemon to pull the nginx
image from a registry.
dockerd
)The Docker Daemon is the background service that does all the heavy lifting. It listens for requests from the client and manages Docker objects such as images, containers, networks, and volumes.
The daemon typically runs as a root-level system service.
Analogy: The daemon is like a chef who receives orders (commands) and prepares the dishes (containers) using the recipes (images).
A Docker Registry is a storage and distribution system for Docker images. Registries can be:
docker pull <image>
– downloads an image from the registrydocker push <image>
– uploads a custom image to the registryRegistries allow teams to share and version application environments easily.
Docker uses several core objects to manage containerized environments:
Here’s the typical flow:
This architecture allows Docker to be powerful, yet simple — separating the user interface (client) from the low-level operations (daemon), and supporting centralized storage (registry) and deployment across multiple systems.
Docker can be installed on Linux, macOS, and Windows. This section will guide you step by step to get Docker up and running on your system.
Follow instructions under https://docs.docker.com/engine/install/
Applications
folderDocker CLI should be available by default. If not, make sure /usr/local/bin/docker
is in your PATH.
Docker Desktop for Windows uses WSL2 or Hyper-V under the hood. You may need to:
On Windows 10/11:
wsl --install
Make sure you have installed a Linux distribution (Ubuntu is fine).
Once Docker is installed, verify that everything is working:
docker --version
Example output:
Docker version 24.0.2, build cb74dfc
docker info
This displays detailed information about your Docker installation: version, storage driver, number of containers, etc.
docker run hello-world
Expected output:
Hello from Docker!
This message shows that your installation appears to be working correctly.
If this works, Docker is correctly installed and functional.
docker
group (see above).The Docker CLI (Command Line Interface) is the main way developers interact with Docker. This section introduces the most commonly used commands that every Docker user should know. Each command includes a description, syntax, and real-life example.
Command | Description | Example |
---|---|---|
docker version | Shows the installed Docker client and daemon versions. | docker version |
docker info | Displays system-wide Docker info, including running containers, images, storage driver, etc. | docker info |
Command | Description | Example |
---|---|---|
docker pull <image> | Downloads an image from Docker Hub or a custom registry. | docker pull nginx |
docker images | Lists all images currently stored on your machine. | docker images |
docker rmi <image> | Removes an image from your system. Useful for cleaning up. | docker rmi nginx |
Command | Description | Example |
---|---|---|
docker run <image> | Creates and starts a new container from an image. | docker run nginx |
docker run -d <image> | Runs the container in detached mode (in the background). | docker run -d nginx |
docker run -p 8080:80 <image> | Maps a container port to a host port. | docker run -p 8080:80 nginx |
docker run --name mycontainer <image> | Assigns a name to the container. | docker run --name webapp nginx |
docker run -v /host:/container <image> | Mounts a volume from host to container. | docker run -v $(pwd):/app myimage |
Command | Description | Example |
---|---|---|
docker ps | Lists running containers. | docker ps |
docker ps -a | Lists all containers (running + stopped). | docker ps -a |
docker logs <container> | Shows logs (stdout/stderr) from a container. | docker logs webapp |
docker inspect <container> | Returns low-level info in JSON format. | docker inspect webapp |
Command | Description | Example |
---|---|---|
docker stop <container> | Gracefully stops a running container. | docker stop webapp |
docker kill <container> | Force-stops a container immediately. | docker kill webapp |
docker rm <container> | Removes a stopped container. | docker rm webapp |
docker rm -f <container> | Force removes a running container. | docker rm -f webapp |
Command | Description | Example |
---|---|---|
docker system prune | Cleans up unused data: stopped containers, unused images, networks, etc. | docker system prune |
docker volume ls | Lists Docker volumes. | docker volume ls |
docker volume rm <name> | Deletes a specific volume. | docker volume rm myvolume |
nginx
image, map port 80
to 8080
, and visit it in your browser.docker ps
.docker logs
and docker inspect
for deeper insights.Now that Docker is installed and you understand its core concepts, it’s time to run your first containers. These exercises will help you verify your setup and introduce you to container basics in action.
hello-world
ContainerThis is the simplest Docker container used to check that Docker is working correctly.
docker run hello-world
hello-world
image is available locally.You should see output like:
Hello from Docker!
This message shows that your installation appears to be working correctly.
If you see this, Docker is successfully installed and working.
Let’s launch a lightweight web server using the official nginx
image.
docker run -d -p 8080:80 nginx
d
: Run in detached mode (in the background).p 8080:80
: Map host port 8080 to container port 80 (nginx serves on port 80).Now open your browser and navigate to:
http://localhost:8080
You should see the default Nginx welcome page.
docker ps
You’ll see the running container with its ID, image, status, and port mapping.
docker logs <container_id>
docker logs nginx_container
This shows you the access logs and startup output.
docker exec -it <container_id> bash
Note: nginx doesn’t include bash by default. Use sh instead:
docker exec -it <container_id> sh
This gives you interactive shell access to the container, just like being logged into a tiny Linux machine.
To stop the container:
docker stop <container_id>
To remove it:
docker rm <container_id>
By now, you’ve:
hello-world
nginx
)