1) What Docker is
Docker is a platform for building, packaging, shipping, and running applications inside containers. Docker uses a client-server model: the docker CLI is the client, dockerd is the daemon, and the daemon manages images, containers, networks, and volumes. Under the hood, Docker Engine uses containerd for container lifecycle management, and containerd typically uses runc to actually create and run containers. (Docker Documentation)
A clean mental model is this:
User → Docker Client (docker) → Docker Daemon (dockerd) → containerd → runc → Linux Kernel
That model is much closer to how Docker works today than “Docker Server” as a generic term. Docker Desktop on macOS and Windows still gives you Docker commands, but Linux containers run inside a Linux VM behind the scenes. (Docker Documentation)
2) Docker on Linux vs Mac
On a Linux server, Docker Engine normally stores its data under /var/lib/docker. That includes images, containers, volumes, networks, and related metadata. (Docker Documentation)
On macOS, Docker Desktop runs Linux containers inside a Linux VM, and the images/containers are stored in Docker Desktop’s disk image rather than directly in /var/lib/docker on the Mac host. That is why users often cannot find the same storage paths on Mac that they see on Linux. (Docker Documentation)
There is another important update for Linux users: on fresh Docker Engine 29+ installations, the containerd image store is the default backend. If a host was upgraded from an older version, it may still use the legacy storage path behavior until the containerd image store is enabled. This explains why image files and overlay directories do not always appear exactly where older tutorials expect them. (Docker Documentation)
3) Filesystem concepts: what belongs in an image and what does not
Your notes mention boot filesystem and kernel, which is a useful teaching angle, but one detail must be corrected:
A Docker image does not contain the Linux kernel. Containers share the host kernel. The image provides the userspace filesystem and application content. (Docker Documentation)
A simpler way to explain filesystem layers is this:
- Kernel = provided by the host OS
- Image = read-only layers containing userspace packages, libraries, configs, and app files
- Container = image + one writable layer on top
So instead of saying “OS inside container = kernel + root fs + user fs + app fs,” the modern and accurate explanation is:
Container runtime view = host kernel + image layers + writable container layer. (Docker Documentation)
4) What is a Docker image?
A Docker image is a packaged, read-only template used to create containers. Images are made of layers, and each layer represents filesystem changes such as adding packages, copying files, or changing configuration. This layered design improves reuse, caching, and storage efficiency. (Docker Documentation)
Examples of base images include:
ubuntudebianalpinefedora
Examples of application images built on top of base images include:
httpdmysqlnginxjenkins/jenkins
In practice, an image is best understood as “a filesystem snapshot plus metadata and startup instructions.” (Docker Documentation)
5) What is a container?
A container is a running instance of an image. When Docker starts a container, it takes the read-only image layers and adds a writable container layer on top. All runtime changes made inside that container are written into that writable layer unless you use volumes or bind mounts. (Docker Documentation)
That writable layer is ephemeral. If the container is deleted, the data in that writable layer is lost unless it was stored in a volume or external mount. This is why databases and Jenkins data should use volumes instead of depending on the container filesystem. (Docker Documentation)
6) Installing Docker on Ubuntu
Your command history is very close to the right process. The current official recommendation is to install Docker Engine from Docker’s APT repository, not from random distro packages, and the standard package set now includes docker-buildx-plugin and docker-compose-plugin. (Docker Documentation)
Use this updated install flow on Ubuntu:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
docker version
docker info
Code language: JavaScript (javascript)
If you want to run Docker without sudo, Docker’s post-installation guidance recommends adding your user to the docker group. (Docker Documentation)
7) First image and first container
To pull an image:
docker pull ubuntu
docker pull httpd
docker images
To run a container from an image:
docker run -d --name web1 httpd
docker ps
docker inspect web1
This is the key concept:
- Image exists first
- Container is created from the image
- One image can create many containers
So the answer to “From image, how do we get containers?” is: Docker starts a container by using the image as the read-only template and adding a writable layer for that container instance. (Docker Documentation)
8) How to create an image
There are two common ways to create an image.
Method 1: Create from an existing container using docker commit
This is good for demos and quick experiments.
Example flow:
docker run -itd --name motox ubuntu
docker exec -it motox /bin/bash
# inside container: apt update && apt install -y git apache2
exit
docker commit -a "Rajesh" -m "Ubuntu with git and apache" motox motoxv2
docker images
docker history motoxv2
Code language: PHP (php)
docker commit captures the container’s filesystem changes into a new image. However, it is not the preferred long-term way to build production images, because it is less reproducible and harder to version-control. Also, commits do not include mounted volume data. (Docker Documentation)
Method 2: Create from a Dockerfile
This is the recommended and professional approach because it is repeatable, reviewable, and version-controlled. Docker’s docs define a Dockerfile as a text file containing instructions used to build an image automatically. (Docker Documentation)
9) Updated Dockerfile tutorial
Your original Dockerfile idea is good, but it should be modernized.
Older teaching example
FROM ubuntu
MAINTAINER Rajesh kumar
RUN apt update
RUN apt install git -y
RUN apt install apache2 -y
COPY index.html /tmp
ENV JAVA_HOME /tmp/java
What should be updated
The MAINTAINER instruction is deprecated. Docker recommends labels instead. Also, combining package installation steps reduces layers and makes builds cleaner. (Docker Documentation)
Better updated example
FROM ubuntu:24.04
LABEL org.opencontainers.image.authors="Rajesh Kumar"
RUN apt-get update && \
apt-get install -y --no-install-recommends apache2 git && \
rm -rf /var/lib/apt/lists/*
COPY index.html /var/www/html/index.html
ENV JAVA_HOME=/opt/java
EXPOSE 80
CMD ["apache2ctl", "-D", "FOREGROUND"]
Code language: JavaScript (javascript)
Build it like this:
docker build -t motoshare:1.0 .
docker images
docker history motoshare:1.0
Code language: CSS (css)
This example is better because it is reproducible, uses a non-deprecated metadata pattern, and defines how the container should start. (Docker Documentation)
10) What is CMD and what is ENTRYPOINT?
This is one of the most important interview and training topics.
CMD
CMD provides the default command or default arguments for the container. If the user supplies a command in docker run, that can replace CMD. (Docker Documentation)
ENTRYPOINT
ENTRYPOINT defines the main executable of the image. Docker’s best-practices guidance says ENTRYPOINT is best used to set the image’s main command, and CMD can then provide default flags or arguments. (Docker Documentation)
Best teaching rule
Use:
- ENTRYPOINT for the fixed main executable
- CMD for default parameters
Example
FROM alpine:3.21
ENTRYPOINT ["ping"]
CMD ["localhost"]
Code language: CSS (css)
Behavior:
docker run myping
# runs: ping localhost
docker run myping google.com
# runs: ping google.com
Code language: CSS (css)
Also remember: if you define multiple CMD or ENTRYPOINT instructions in one stage, only the last one is used. (Docker Documentation)
11) How to share an image
There are two main ways to share Docker images.
Option 1: Push to a registry
This is the normal team or production method.
docker login
docker tag motoshare:1.0 yourdockerhubuser/motoshare:1.0
docker push yourdockerhubuser/motoshare:1.0
Docker’s build-and-publish documentation recommends building, tagging, and publishing images to Docker Hub or another registry. Tags help identify versions. (Docker Documentation)
Option 2: Save to a tar file
This is useful for offline transfer.
docker save -o motoshare.tar motoshare:1.0
docker load -i motoshare.tar
Code language: CSS (css)
docker image save exports image data into a tar archive, and docker image load restores images and tags from that archive. (Docker Documentation)
12) Where image files are stored
This part connects directly to your command history.
On Linux, Docker daemon data is usually under /var/lib/docker. But depending on your Docker version and storage backend, you may not see the exact old-style overlay paths you expect. With newer setups, containerd’s image store may be in use, and snapshot data may be managed differently. (Docker Documentation)
So if someone asks:
“Where is the image path?”
The modern answer is:
- On Linux, start with
/var/lib/docker - Check
docker infoto see the storage driver and data root - On newer systems, image and snapshot handling may involve containerd storage backends
- On Mac, images are usually inside Docker Desktop’s Linux VM disk image, not plain host directories (Docker Documentation)
13) Jenkins example in Docker
Since your notes mention Jenkins, the best practical teaching advice is: for Jenkins, prefer the official Jenkins Docker image instead of manually assembling Jenkins from raw Ubuntu unless your goal is specifically to teach image construction. Jenkins’ official docs include Docker-based installation guidance using the jenkins/jenkins image. (Jenkins)
A simple example is:
docker run -d \
--name jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts-jdk17
Code language: JavaScript (javascript)
This is a good example of why volumes matter: Jenkins data should live in a persistent volume, not only inside the container writable layer. (Jenkins)
14) Best-practice summary
Use this as the “final takeaway” section in your tutorial:
- Docker images are layered, read-only templates. (Docker Documentation)
- Containers are running instances of images with a writable layer. (Docker Documentation)
- Containers do not bring their own kernel; they use the host kernel. (Docker Documentation)
- On Mac and Windows, Linux containers usually run inside a VM provided by Docker Desktop. (Docker Documentation)
docker commitis okay for learning and debugging, but Dockerfiles are the preferred way to create production images. (Docker Documentation)- Use
ENTRYPOINTfor the main executable andCMDfor default arguments. (Docker Documentation) - Share images through Docker Hub/private registries or with
docker saveanddocker load. (Docker Documentation) - Use volumes for persistent data such as Jenkins home, MySQL data, and application uploads. (Docker Documentation)
15) Suggested assignments for students
Assignment 1
Pull the ubuntu image, inspect it, and explain why it is an image and not a running container.
Assignment 2
Run two containers from the same httpd image and prove that one image can create multiple containers.
Assignment 3
Create a custom image by:
- starting an Ubuntu container
- installing
gitandapache2 - committing it as
motoxv2
Then compare docker history ubuntu and docker history motoxv2.
Assignment 4
Write a Dockerfile that:
- starts from Ubuntu
- installs
apache2 - copies
index.html - starts Apache in the foreground
Assignment 5
Create one image using CMD only, and another using ENTRYPOINT + CMD, then observe how docker run arguments behave.
Assignment 6
Share your image in two ways:
- push to Docker Hub
- export with
docker saveand restore withdocker load
16) One-line short definition set for training slides
You can use these directly in slides:
Docker: A container platform for building, shipping, and running applications.
Image: A read-only layered template used to create containers.
Container: A running instance of an image with a writable layer.
Dockerfile: A text file containing instructions to build an image.
dockerd: The Docker daemon that manages Docker objects.
containerd: Runtime component used by Docker for container lifecycle management.
CMD: Default command or arguments for a container.
ENTRYPOINT: Main executable of the container image.
Volume: Persistent storage used by containers.