DevOps.Academy
CoursesCurriculumPricing

    Loading…

    ↑ ↓ move · ↵ open · Ctrl K anywhere

    ◔My learningSign in
    Join the waitlist
    DevOps.Academy

    Free, hands-on DevOps lessons. Made with care in India.

    Learn

    All coursesLinux roadmapCurriculumMy learning

    Academy

    PricingCertificates

    Legal

    PrivacyTermsContact

    devops.rajeev.pro

    DockerLesson 1 of 14
    Your progress · 0%
    On this page
    1. "It works on my machine"
    2. What a container actually is
    3. Bare metal, VMs and containers
    4. Docker and OCI
    ↖ Course roadmap
    Lesson 1 · Introduction

    Containers: what they are and why they won

    What a container really is, why "it works on my machine" stopped being an excuse, how containers differ from VMs and bare metal, and where Docker and OCI fit.

    20 min read · beginner · hands-on

    By the end of this lesson you'll be able to

    0 of 4 complete

    "It works on my machine"

    The app runs perfectly on your laptop. On the server it crashes, because the server has Python 3.10 and you have 3.12, or a library is a different version, or a config file is in a different place. Every team has lost days to this.

    Containers fix it by shipping the app together with everything it needs: the runtime, the libraries, the system tools and the config defaults, all frozen into one image. If the image runs on your laptop, the same image runs the same way on the server, in CI and on your colleague's machine.

    That one property changes a lot:

    • Developers stop writing "install these 14 things" in the README. docker run is the setup.
    • Operations gets one way to run every app, whatever language it's written in.
    • Pipelines build one artifact and deploy it everywhere, as the CI/CD course explains.
    • Density. Many isolated apps can share one server without fighting over library versions.

    What a container actually is

    A container is a normal Linux process that the kernel isolates. It's not a small VM and there's no second operating system inside it. Two kernel features do the work:

    • Namespaces change what the process can see: its own process list, its own network interfaces, its own hostname and its own filesystem.
    • cgroups limit what it can use: how much CPU, memory and I/O.

    The filesystem comes from the image: a read-only stack of layers holding the app and its dependencies. When a container starts, it gets a thin writable layer on top, which disappears when the container is removed.

    You can see the isolation yourself:

    $ docker run --rm alpine ps              # the process list inside a new container
    PID   USER     TIME  COMMAND
        1 root      0:00 ps
    $ docker run --rm alpine cat /etc/os-release | head -n 2
    NAME="Alpine Linux"
    ID=alpine
    
    docker run --rm alpine ps
    • dockerbuild and run containers
    • runstart a new container
    • --rmdelete the container when it exits
    • alpinea value the command works on
    • psa value the command works on
    docker run --rm alpine cat /etc/os-release | head -n 2
    • dockerbuild and run containers
    • runstart a new container
    • --rmdelete the container when it exits
    • alpinea value the command works on
    • cata value the command works on
    • /etc/os-releasea path
    • |pipe: send output to the next command
    • headshow the first lines
    • -nhow many lines
    • 2a value the command works on

    Inside the container, ps is PID 1 and sees nothing else on your machine, and the filesystem is Alpine Linux, whatever your host runs. --rm deletes the container when it exits, so you don't collect stopped containers while you experiment.

    Bare metal, VMs and containers

    A VM virtualises the hardware and brings its own kernel. A container isolates processes on the one kernel the host already has.© Diagram: DevOps Academy

    A VM virtualises the hardware and brings its own kernel. A container isolates processes on the one kernel the host already has.© Diagram: DevOps Academy
    Bare metalVirtual machineContainer
    What you getA whole physical serverA full OS with its own kernelIsolated processes on the host kernel
    Starts inMinutes (boot the hardware)Tens of seconds to minutesUsually under a second
    SizeThe whole machineGigabytesMegabytes to a few hundred MB
    IsolationCompleteStrong: separate kernelsGood, but one shared kernel
    Use it forDatabases, raw performanceDifferent OSes, strong tenant isolationApps and services, CI jobs, microservices

    They aren't rivals. In the cloud you'll nearly always run containers inside VMs: the VM gives you strong isolation from other customers, and containers let you pack many apps onto it.

    On a Mac or Windows

    Containers need a Linux kernel, so Docker Desktop quietly runs a small Linux VM and your containers run inside it. That's why uname -r in a container shows a different kernel from your Mac's. On a Linux server there's no VM: the container uses the host's kernel directly.

    Docker and OCI

    Docker made containers easy in 2013 with three ideas: a simple file to describe an image (the Dockerfile), a command line that builds and runs it (docker build, docker run), and a registry to share images (Docker Hub). The kernel features existed before; Docker made them usable.

    Under the hood, Docker is several pieces:

    PieceDoes
    docker CLIWhat you type. Sends requests to the engine
    Docker Engine (dockerd)Builds images, manages containers, networks and volumes
    containerdRuns and supervises containers. Kubernetes uses it directly
    runcTalks to the kernel to create the namespaces and cgroups

    The Open Container Initiative (OCI) turned the image format and the runtime into open standards. That's why an image you build with Docker also runs on Podman, on containerd, on Kubernetes and on every cloud container service. Learn Docker and you've learned how containers work everywhere.

    $ docker run hello-world
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    ...
    $ docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    alpine        latest    ...            ...            ~8MB        # yours will differ a little
    hello-world   latest    ...            ...            a few kB
    
    docker run hello-world
    • dockerbuild and run containers
    • runstart a new container
    • hello-worlda value the command works on
    docker images
    • dockerbuild and run containers
    • imageslist images
    A shared kernel is a shared risk

    Containers are isolated, but not as strongly as VMs: a kernel bug can let a process escape. Don't run containers as root unless you need to, and don't run untrusted images. The Security stage of this course covers how.

    In production

    Pin images to a version tag, like node:22-alpine, never just latest. latest is whatever was pushed most recently, so the same deploy can run different code on Monday and on Friday.

    ⌘
    Mini mission

    Prove a container shares the host kernel

    A teammate insists every container runs its own operating system, like a VM. Settle it on a Linux machine: record the host's kernel version and the kernel version seen from inside an Alpine container, side by side in one file.

    Input: A Linux host with DockerOutput: ~/kernel-check.txt
    Reveal one safe solution
    $ echo "host:      $(uname -r)" > ~/kernel-check.txt
    $ echo "container: $(docker run --rm alpine uname -r)" >> ~/kernel-check.txt
    $ cat ~/kernel-check.txt
    host:      6.8.0-48-generic
    container: 6.8.0-48-generic
    
    echo "host: $(uname -r)" > ~/kernel-check.txt
    • echoprint text
    • "host: $(uname -r)"text, kept together by the quotes
    • >write output to a file, replacing it
    • ~/kernel-check.txta path
    echo "container: $(docker run --rm alpine uname -r)" >> ~/kernel-check.txt
    • echoprint text
    • "container: $(docker run --rm alpine uname -r)"text, kept together by the quotes
    • >>append output to a file
    • ~/kernel-check.txta path
    cat ~/kernel-check.txt
    • catprint a file
    • ~/kernel-check.txta path

    The numbers match because there's only one kernel. The container's files say Alpine, but the kernel underneath is the host's. On Docker Desktop you'll see the kernel of its Linux VM instead, which proves the same point.

    Try it yourself

    0 of 5 steps done

    Run each task in your own account or terminal, then tick it off.

    Knowledge check

    Quick check

    Question 1 of 4

    What does every container on a Linux host share with the host?

    Go deeper

    Official reading for this lesson

    • GuideWhat is a container?Docker ↗
    • DocsDocker overviewDocker Docs ↗
    • DocsInstall Docker Engine on LinuxDocker Docs ↗
    • DocsDocker DesktopDocker Docs ↗
    • GuideOpen Container InitiativeOCI ↗
    • DocsOCI image specificationOCI on GitHub ↗
    • Docsnamespaces(7): the kernel feature behind isolationUbuntu manpages ↗

    Or get every quiz answer right and it completes itself.

    Next lesson →Under the hood