Skip to main content

Command Palette

Search for a command to run...

🐳 Docker – Day 1: Container Fundamentals

Why Containers Exist and How Docker Actually Works (Production View)

Updated
8 min read
🐳 Docker – Day 1: Container Fundamentals

🎯 Purpose of Day 1 (Why This Day Matters)

Most people learn Docker commands.
Very few people understand why Docker behaves the way it does.

This gap causes:

  • Confusion during incidents

  • Wrong architectural decisions

  • Fear of containers in production

  • Blind copy-pasting of Dockerfiles

Day 1 is about fixing the mental model.

If you understand why containers exist and how Docker uses Linux internals, everything else (Dockerfiles, Kubernetes, CI/CD) becomes logical instead of magical.

📌 The Real Problem Containers Were Created to Solve

Before Containers (Reality)

Teams faced:

  • Applications tightly coupled to OS versions

  • Dependency conflicts (Python, OpenSSL, libc)

  • Environment drift between dev, QA, prod

  • Manual server setup and snowflake servers

  • Heavy virtual machines for small services

Even with configuration management:

  • Provisioning was slow

  • Rollbacks were painful

  • Debugging environment issues wasted time

📌 The core problem was not deployment — it was consistency.

🧠 Why Virtual Machines Were Not Enough

What is a Container? | Docker

Virtual Machines solved isolation, but introduced new problems:

VM Problem Impact
Full OS per app High memory & CPU usage
Slow boot time Poor scaling
Heavy disk images Slow CI/CD
OS patching per VM Operational overhead

📌 VMs isolate hardware
📌 Containers isolate processes

This distinction is critical.

🔍 What a Container REALLY Is (How It Works Internally)

A container is just a Linux process running with restrictions.

Docker uses Linux kernel features, not magic:

1️⃣ Namespaces (Isolation)

Namespaces isolate:

  • Process IDs (PID)

  • Network interfaces

  • Mount points

  • Users

  • Hostnames

👉 This is why a container thinks it’s alone.


2️⃣ cgroups (Resource Control)

Control:

  • CPU usage

  • Memory limits

  • Disk I/O

👉 This prevents one container from starving others.


3️⃣ Union Filesystems (Images)

Images are built using layered filesystems:

  • Read-only base layers

  • Thin writable layer per container

👉 This makes images:

  • Small

  • Fast

  • Reusable

📌 Containers share the same kernel, not the same filesystem.

⚠️ Key Understanding (Most Important Line)

Containers are isolated processes, not isolated operating systems

This explains:

  • Why containers start in milliseconds

  • Why kernel bugs affect all containers

  • Why you can’t run Windows containers on Linux hosts

  • Why containers feel “lightweight”

🧰 What Docker Actually Does (How Docker Fits In)

Docker is not the container technology.

Docker is:

  • A CLI + API

  • A daemon (dockerd)

  • A workflow engine

Docker handles:

  • Image building

  • Image storage

  • Container lifecycle

  • Networking

  • Volumes

Under the hood:

📦 Image vs Container (Why the Difference Exists)

Docker for Beginners: An Introduction to Docker, Images, and Containers

Docker Image (WHY)

  • Immutable

  • Versioned

  • Portable

  • Reproducible

Purpose:

“Build once, run anywhere”


Docker Container (WHY)

  • Runtime execution

  • Disposable

  • Ephemeral

Purpose:

“Run, fail, destroy, replace”

📌 This is why containers should never store important data.

❌ Common Wrong Mental Model (Very Costly in Production)

Treating containers like servers

Examples:

  • SSH into containers

  • Apply hotfixes inside containers

  • Store logs and data inside container filesystem

Why this fails:

  • Containers are replaceable

  • Changes are lost on restart

  • Scaling breaks stateful assumptions

📌 Containers should be immutable at runtime.

🧰 Docker Installation (Environment Setup)

Docker installation steps vary across operating systems (Ubuntu, RHEL/CentOS, macOS, Windows).
To avoid misconfiguration, always refer to the official Docker documentation for your specific OS.

👉 Official docs: https://docs.docker.com/engine/install/

Below are the recommended and production-safe steps for Ubuntu, which I am using in this setup.

OS requirements

To install Docker Engine, you need the 64-bit version of one of these Ubuntu versions:

Docker Engine for Ubuntu is compatible with x86_64 (or amd64), armhf, arm64, s390x, and ppc64le (ppc64el) architectures.

📦 Step 1: Update the system

sudo apt update && sudo apt upgrade -y

Uninstall old versions

Before you can install Docker Engine, you need to uninstall any conflicting packages.

Your Linux distribution may provide unofficial Docker packages, which may conflict with the official packages provided by Docker. You must uninstall these packages before you install the official version of Docker Engine.

The unofficial packages to uninstall are:

Moreover, Docker Engine depends on containerd and runc. Docker Engine bundles these dependencies as one bundle: containerd.io. If you have installed the containerd or runc previously, uninstall them to avoid conflicts with the versions bundled with Docker Engine.

Run the following command to uninstall all conflicting packages:

sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc | cut -f1)

Install using the apt repository

Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker apt repository. Afterward, you can install and update Docker from the repository.

Set up Docker's apt repository.

# Add Docker's official GPG key:
sudo apt update
sudo apt install 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

# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: \((. /etc/os-release && echo "\){UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

Install the Docker packages.

Latest Specific version

To install the latest version, run:

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

The Docker service starts automatically after installation. To verify that Docker is running, use:

 saad@saad-VirtualBox:~$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Mon 2025-12-22 21:15:28 IST; 12s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 5571 (dockerd)
      Tasks: 11
     Memory: 27.6M (peak: 28.0M)
        CPU: 1.250s
     CGroup: /system.slice/docker.service
             └─5571 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Dec 22 21:15:27 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:27.119693338+05:30" level=info msg="Restoring containers: start."
Dec 22 21:15:27 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:27.218629521+05:30" level=info msg="Deleting nftables IPv4 rules" error=>
Dec 22 21:15:27 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:27.232686953+05:30" level=info msg="Deleting nftables IPv6 rules" error=>
Dec 22 21:15:28 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:28.153345248+05:30" level=info msg="Loading containers: done."
Dec 22 21:15:28 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:28.217996669+05:30" level=info msg="Docker daemon" commit=fbf3ed2 contai>
Dec 22 21:15:28 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:28.218959682+05:30" level=info msg="Initializing buildkit"
Dec 22 21:15:28 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:28.272468886+05:30" level=info msg="Completed buildkit initialization"
Dec 22 21:15:28 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:28.284516694+05:30" level=info msg="Daemon has completed initialization"
Dec 22 21:15:28 saad-VirtualBox dockerd[5571]: time="2025-12-22T21:15:28.284657525+05:30" level=info msg="API listen on /run/docker.sock"
Dec 22 21:15:28 saad-VirtualBox systemd[1]: Started docker.service - Docker Application Container Engine.

Some systems may have this behavior disabled and will require a manual start:

 sudo systemctl start docker

saad@saad-VirtualBox:~$ docker version
Client: Docker Engine - Community
 Version:           29.1.3
 API version:       1.52
 Go version:        go1.25.5
 Git commit:        f52814d
 Built:             Fri Dec 12 14:49:32 2025
 OS/Arch:           linux/amd64
 Context:           default
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock

Verify that the installation is successful by running the hello-world image:

saad@saad-VirtualBox:~$ sudo docker run hello-world
[sudo] password for saad:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
17eec7bbc9d7: Pull complete
ea52d2000f90: Download complete
Digest: sha256:d4aaab6242e0cace87e2ec17a2ed3d779d18fbfd03042ea58f2995626396a274
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

This command downloads a test image and runs it in a container. When the container runs, it prints a confirmation message and exits.

Day 1 Summary – Docker Fundamentals & Environment Setup

Docker Day 1 focused on establishing both conceptual clarity and a working Docker environment. Along with installing Docker correctly and validating the runtime using a Hello World container, this day clarified why Docker exists and how it differs from traditional virtual machines. We covered the core distinction between VMs and containers, highlighting how containers share the host kernel, start faster, and consume fewer resources—making them better suited for modern CI/CD and microservice-based architectures. The difference between Docker images and containers was also introduced early to avoid common production misconceptions: images as immutable blueprints and containers as disposable runtime instances. By the end of Day 1, the Docker daemon was verified, the container lifecycle was validated, and the foundational mental model was established—ensuring the system and the understanding are both ready for deeper Docker internals in Day 2.