Docker Fundamentals, Images, Containers, Dockerfile, and Image Sharing

DevOps

YOUR COSMETIC CARE STARTS HERE

Find the Best Cosmetic Hospitals

Trusted • Curated • Easy

Looking for the right place for a cosmetic procedure? Explore top cosmetic hospitals in one place and choose with confidence.

“Small steps lead to big changes — today is a perfect day to begin.”

Explore Cosmetic Hospitals Compare hospitals, services & options quickly.

✓ Shortlist providers • ✓ Review options • ✓ Take the next step with confidence

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) → containerdrunc → 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:

  • ubuntu
  • debian
  • alpine
  • fedora

Examples of application images built on top of base images include:

  • httpd
  • mysql
  • nginx
  • jenkins/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 info to 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:

  1. Docker images are layered, read-only templates. (Docker Documentation)
  2. Containers are running instances of images with a writable layer. (Docker Documentation)
  3. Containers do not bring their own kernel; they use the host kernel. (Docker Documentation)
  4. On Mac and Windows, Linux containers usually run inside a VM provided by Docker Desktop. (Docker Documentation)
  5. docker commit is okay for learning and debugging, but Dockerfiles are the preferred way to create production images. (Docker Documentation)
  6. Use ENTRYPOINT for the main executable and CMD for default arguments. (Docker Documentation)
  7. Share images through Docker Hub/private registries or with docker save and docker load. (Docker Documentation)
  8. 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 git and apache2
  • 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 save and restore with docker 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.