DevOps

Docker Fundamentals for Beginners: Understand Containers and Images

Introduction

Docker fundamentals are essential for infrastructure professionals working with modern applications, cloud platforms, and DevOps environments. If you’re managing infrastructure at scale, you’ve probably heard of Docker

The problem is most Docker tutorials treat you like you’re building a microservices platform on day one. They skip the fundamentals and jump straight to deployment patterns.

This guide is different.

We’re going to start at the beginning: What is Docker? Why should infrastructure professionals care? How do containers actually work? And—most importantly—how is this different from virtual machines?

By the end of this article, you’ll understand:

  • The difference between containers and VMs
  • How Docker images work
  • How to run your first container
  • The Docker architecture and components
  • Why Docker matters for your infrastructure career

You don’t need any Docker experience to read this. If you can manage VMs and understand Linux, you already have the foundational knowledge we’re building on.

Let’s start.


What Is Docker? (The Simple Version)

Docker is a containerization platform. That’s the technical answer.

Here’s the practical answer: Docker lets you package an application—and its dependencies—into a standardized image that can be used to create containers consistently across different environments.

Think of it like this:

You’re building a house. Normally, you’d give a contractor a list of materials:

  • Use these specific bricks
  • This brand of mortar
  • These windows
  • This roofing material

The contractor gets it mostly right, but your house in Arizona might have different framing than your house in Minnesota. Things break in unexpected ways.

With Docker, you define the application environment and its dependencies in a standardized image. The same image can then be used to create containers on your laptop, a test server, or a production environment.

Your application is the house. The Docker image is the standardized package used to create that house consistently.


Containers vs. Virtual Machines: The Key Difference

This is the most important concept to understand.

You know VMs. They’ve been around since the 2000s. You probably manage 50-200 of them right now.

When you create a VM:

  1. You allocate CPU and RAM
  2. You install an operating system
  3. You install dependencies (Java, databases, libraries)
  4. You deploy your application

A typical VM may use:

  • Several GB of RAM
  • Significant disk space for the guest operating system
  • Additional CPU and storage resources for the guest OS

A container typically uses significantly fewer resources because it shares the host operating system kernel rather than running a complete guest OS.

The difference: VMs include a full guest operating system. Linux containers don’t.

The Architecture Difference

VIRTUAL MACHINES:
┌────────────────────────────────┐
│  Application                   │
│  Libraries & Dependencies      │
│  Guest OS (Ubuntu/Windows)     │  ← Full OS
│  Hypervisor                    │
├────────────────────────────────┤
│  Host OS / Hypervisor          │
└────────────────────────────────┘

CONTAINERS:
┌────────────────────────────────┐
│  Application                   │
│  Libraries & Dependencies      │  ← No guest OS
│  Container Runtime             │
├────────────────────────────────┤
│  Host OS / Linux Kernel        │  ← Shared
└────────────────────────────────┘

Why this matters:

  • VMs: Strong isolation. Higher resource overhead because each VM includes a guest OS.
  • Containers: Lightweight. Fast to start. Multiple containers can share the host kernel.

A server with 32 GB RAM might run several VMs, while a container host can potentially run many more containers depending on the workload and resource requirements.

The actual capacity depends on the workload. A lightweight web service and a memory-heavy application will have very different resource requirements.

Example from the real world:

At my current company, we migrated a legacy Windows application to Docker. Before containerization:

10 VMs × 8GB RAM each = 80 GB memory allocated
10 VMs × 2 vCPUs = 20 vCPU allocated
Startup time: several minutes
Restart for updates: significant maintenance time

After containerization:

80 containers × 256 MB RAM each = 20 GB memory allocated
Shared kernel and container runtime
Startup time: significantly reduced
Restart: significantly reduced

The actual results depend on the application, container configuration, and infrastructure.

That’s one reason containers are widely used in modern cloud and application environments.

Docker Fundamentals: How Docker Actually Works

Docker isn’t magic. It’s built on operating-system features such as namespaces and control groups that provide process isolation and resource management.

The Four Core Concepts

1. Images

A Docker image is a template. It’s a packaged, read-only set of files and metadata used to create containers.

An image can include:

  • A base filesystem (Alpine Linux, Ubuntu, etc.)
  • Application dependencies
  • Your application code
  • Configuration defaults
  • Instructions for how to run the application

Images are immutable by design. When you need to change an image, you normally build a new image version rather than modifying the existing image.

Example image:

Ubuntu base + Node.js runtime + application code

2. Containers

A container is a running instance of an image.

You can have one image and run multiple containers from it. Each container has its own isolated process, filesystem view, network configuration, and other resources.

Analogy:

Image = class, Container = object instance

3. Registries

A registry is a repository for container images. Think of it as a central place for storing and distributing images.

One of the most common public registries is Docker Hub.

Examples of images available on Docker Hub include:

  • ubuntu – Ubuntu base image
  • nginx – Web server
  • postgres – Database
  • node – Node.js runtime

You push (upload) images to a registry. You pull (download) images from a registry.

Private registries can also be used by organizations to store internal application images.

4. The Docker Daemon

On traditional Docker Engine installations, the Docker daemon is a background service that manages containers and other Docker objects.

When you type:

docker run

the Docker CLI communicates with the Docker Engine to create and start a container from an image.

The Docker Engine handles tasks such as:

  • Creating containers
  • Managing container lifecycle
  • Managing networking
  • Managing storage
  • Starting and stopping containers

How Docker Uses Linux Kernel Features

Docker works by using operating-system features to provide isolation and resource control.

Namespaces

Namespaces isolate system resources. Linux containers can have isolated:

  • Network namespace
  • PID namespace
  • Mount namespace
  • IPC namespace
  • UTS namespace

From inside a container, processes see an isolated environment while the host operating system manages the underlying resources.

Cgroups (Control Groups)

Cgroups, or control groups, allow Linux to control and account for resource usage.

They can be used to manage resources such as:

  • CPU
  • Memory
  • Block I/O

For example:

Container A → CPU limit
Container B → Memory limit
Container C → I/O limit

This helps prevent a single container from consuming unlimited resources.

Union Filesystems

Docker images are built from layers:

Layer 1: Ubuntu base
Layer 2: Add Node.js
Layer 3: Add application code
─────────────────────────────
Combined image

Multiple images can reuse common layers, which can reduce storage requirements and make image distribution more efficient.


Your First Container: Docker Run

Let’s run a real example.

Step 1: Install Docker

On Ubuntu, you can install Docker using Docker’s official installation instructions.

For a quick test environment, Docker also provides an installation script:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

For production environments, review Docker’s official installation documentation and follow the supported installation method for your operating system.

Verify:

docker --version

Example:

Docker version 24.0.0

The exact version will depend on the Docker release installed on your system.

Step 2: Run a Simple Container

Let’s start Nginx:

docker run -d --name web-server -p 80:80 nginx

What just happened?

  • docker run = Create and start a container
  • -d = Detached (run in background)
  • --name web-server = Name this container
  • -p 80:80 = Port mapping (host port 80 → container port 80)
  • nginx = Image to use (Docker downloads it if you don’t have it)

Check it’s running:

docker ps

Example:

CONTAINER ID   IMAGE    COMMAND                  STATUS
abc123def456   nginx    "/docker-entrypoint.s…" Up 2 minutes

Visit:

http://localhost

in your browser. You’ll see the Nginx welcome page.

Step 3: Inspect the Container

docker logs web-server

See container output.

You can also open a shell inside the container:

docker exec -it web-server /bin/bash

Inside the container, try:

ls /

You may see directories such as:

bin
boot
dev
etc
home
lib
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

You can also inspect the container configuration:

docker inspect web-server

Step 4: Stop and Remove

docker stop web-server

Gracefully stop the container.

Then:

docker rm web-server

Remove the container.

The Nginx image remains available locally.

That’s containerization. You created and started a container from an existing image with a single command.


Building Your Own Image: Dockerfile

Running existing images is useful, but the real power is building custom images.

What’s a Dockerfile?

A Dockerfile is a text file containing instructions for building a Docker image.

Think of it as a recipe for creating your application image.

Example Dockerfile:

# Start from Ubuntu
FROM ubuntu:20.04

# Install dependencies
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    && rm -rf /var/lib/apt/lists/*

# Copy your app into the container
COPY app.py /app/app.py

# Set working directory
WORKDIR /app

# Document the application port
EXPOSE 5000

# Command to run when container starts
CMD ["python3", "app.py"]

Building an Image

docker build -t my-app:1.0 .
  • -t = tag (name:version)
  • . = current directory (Docker looks for the Dockerfile here)

Docker processes the Dockerfile instructions and builds the image.

Conceptually:

  1. Pulls the Ubuntu base image
  2. Installs Python and pip
  3. Copies your application
  4. Sets the working directory
  5. Documents the application port
  6. Records the startup command

Result:

my-app:1.0

Running Your Custom Image

docker run -d -p 5000:5000 my-app:1.0

The container now runs your Python application.

This is powerful: You can package your application and its dependencies into an image and move that image between environments instead of manually repeating the installation process.


Key Docker Concepts Explained

Ports and Port Mapping

Containers have their own network namespace. Your application can listen on a port inside the container.

But that port is not automatically exposed on the host.

You can map it:

docker run -p 8000:5000 my-app:1.0

This means:

Host port 8000 → Container port 5000

Visit:

http://localhost:8000

to access the application.


Volumes and Persistent Data

Containers are often treated as ephemeral. Changes made inside a container’s writable layer are not a good place to store important persistent application data.

For databases and other persistent workloads, you can use volumes:

docker volume create postgres-data

docker run \
    -v postgres-data:/var/lib/postgresql/data \
    postgres

The volume exists independently from the container, so the data can survive container removal and recreation.


Environment Variables

You can pass configuration to containers without rebuilding the image:

docker run \
    -e DATABASE_URL=postgres://user:pass@db:5432/app \
    my-app:1.0

Inside the container, the application can read the DATABASE_URL environment variable.

Important: Don’t put real production passwords or secrets directly into command history or Docker images. Use appropriate secret-management mechanisms for production environments.


Networking

Containers can communicate through Docker networks.

Create a network:

docker network create mynet

Run a database container:

docker run -d \
    --network mynet \
    --name db \
    postgres

Run your application:

docker run -d \
    --network mynet \
    --name my-app \
    -p 8000:5000 \
    my-app:1.0

Containers connected to the same user-defined Docker network can communicate with each other using container names as DNS names.

For example, an application could connect to:

db

instead of needing to know the database container’s IP address.


Docker for Infrastructure Professionals: Why You Need This

Let me be direct: Docker is changing infrastructure roles.

What’s Changing

5 years ago: Infrastructure = VMs + storage + networking + backups

Today: Infrastructure increasingly includes containers + orchestration + monitoring + security

The job isn’t disappearing. It’s evolving.

Where Docker Fits in Your Career

As an infrastructure professional, Docker is relevant for:

  1. Application Deployment – You’ll increasingly work with containerized applications, not just VMs
  2. Monitoring – Container health, resource usage, and logs introduce different operational considerations
  3. Networking – Container networks and service discovery introduce new concepts
  4. Security – Container isolation, image scanning, and registry security
  5. Automation & Reproducibility – Dockerfiles define image builds in a repeatable, version-controlled way

If you’re targeting DevOps or Cloud Engineer roles, practical Docker skills are increasingly important.

Real Example: What Your Future Looks Like

Current state:

Request: Deploy a Java app
You: Create a VM, install Java, deploy WAR file, configure firewall rules
Time: Potentially significant manual effort
Risk: Dependency conflicts, configuration mistakes

Future state:

Developer: Here's the Docker image
You: Run and manage the container
Time: Reduced deployment effort
Risk: Fewer manual dependency-installation steps

The exact process depends on the application and the platform you’re using.


Docker Limitations (Be Honest)

Docker isn’t perfect. Here are real limitations:

  1. Linux containers require a Linux kernel – On Windows and macOS, Docker Desktop provides a Linux environment for Linux containers. Windows containers are also supported but use a different architecture.
  2. Stateful Apps – Databases in containers work, but stateful workloads require careful storage, backup, and operational planning.
  3. Requires Orchestration at Scale – One container is simple. Managing hundreds of containers introduces the need for orchestration and operational tooling such as Kubernetes.
  4. Container Sprawl – It’s easy to create lots of containers. Managing them requires proper processes, monitoring, and lifecycle management.
  5. Not a VM Replacement – If you need full OS isolation or applications that specifically require a traditional Windows environment, VMs are still appropriate.

Docker solves specific problems really well. It’s not a universal solution.


What’s Next?

Now that you understand Docker fundamentals, where do you go?

Next in this series:

  1. Docker Images & Dockerfile Best Practices – Learn to build production-grade images
  2. Docker Networking & Volumes – Connect containers and manage data
  3. Docker Compose – Orchestrate multiple containers
  4. Docker Security – Secure containers for production
  5. Docker Performance – Optimize and monitor

Each article builds on this foundation.

Practical Next Steps:

  1. Install Docker on your personal machine
  2. Run 5-10 existing images from Docker Hub
  3. Build a simple Dockerfile for an app you know
  4. Run your image and verify it works
  5. Read Article 2 when ready

Key Takeaways

Docker fundamentals boil down to this:

✓ Containers = lightweight, isolated units of application execution
✓ Images = read-only templates used to create containers
✓ Registries = central storage for container images
✓ Docker Engine = software responsible for building and running containers
✓ Kernel features = namespaces and cgroups provide isolation and resource control

✓ Why it matters = reproducible application environments, easier deployment, and more efficient resource usage
✓ Your role = deploying, securing, monitoring, and managing containerized infrastructure

Docker is not a trend. It’s an important part of modern application and infrastructure environments.

Start learning now. Your next step is understanding how Docker images and Dockerfiles are built.


Resources

Mo Assem

My name is Mohamed Assem, and I am a Cloud & Infrastructure Engineer with over 14 years of experience in IT, working across both Microsoft Azure and AWS. My expertise lies in cloud operations, automation, and building modern, scalable infrastructure. I design and implement CI/CD pipelines and infrastructure as code solutions using tools like Terraform and Docker to streamline operations and improve efficiency. Through my blog, TechWithAssem, I share practical tutorials, real-world implementations, and step-by-step guides to help engineers grow in Cloud and DevOps.

Related Articles

Leave a Reply

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

Back to top button