Docker packages an application with everything it needs to run, so it behaves the same on your laptop, in testing, and in production.
It is for developers and teams who have hit the "it works on my machine" problem. An app runs fine for one person, then breaks somewhere else.
Without it, a team keeps hitting bugs that only show up on some machines. Each computer has slightly different versions of the same tools installed.
The problem, "it works on my machine"
When a team builds an app, each developer's computer, the test system, and the production server run it separately. Each of those can end up with slightly different versions of the same tools, such as Node, Python, or the database. That mismatch is what breaks an app that worked fine for one person but fails for another.
A web app has a React frontend, a Python API, and a PostgreSQL database. One developer has a newer version of Python installed than the person testing the app. A bug shows up only in testing because of that difference.
The technical details
Docker Docs frames this as separating an application from its infrastructure. "Docker enables you to separate your applications from your infrastructure so you can deliver software quickly."
Without that separation, a team has to manually keep the exact same language runtime, database, and library versions in sync. That sync has to hold across every developer's machine, the automated test system (often called CI, for continuous integration), and production. Any drift between them can reintroduce the bug.
Images vs. containers
An image is a read-only template that contains an application and everything it needs to run. A container is that template running as a live process on a machine. You can start many containers from the same image, and each one runs independently.
A PostgreSQL image packages the database binaries, its config files, and its other dependencies. Running that image starts a container, a running database process, isolated from anything else on the machine.
The technical details
Docker's own docs state two core principles of images. They are immutable, meaning once built, an image can't be changed, only extended into a new image. They are also composed of layers, where each layer is a set of filesystem changes.
A container is described as "a runnable instance of an image."
It can be started, stopped, moved, or deleted independently of other containers, and by default it runs in a loosely isolated environment. When a container is removed, any changes to its state that were not stored in separate persistent storage disappear.
From Dockerfile to running container
You describe how to build an application's environment in a text file called a Dockerfile. Docker turns that file into an image, which you push to a shared storage location called a registry. Anyone can then pull it down and run it as a container, on their own machine or anywhere else.
A developer writes a Dockerfile that starts from a base Node.js image, copies in their app's code, and installs its dependencies. They build it into an image, push it to Docker Hub, and a teammate pulls the exact same image to run locally.
The technical details
A Dockerfile typically follows four steps, per Docker's own docs.
- Determine a base image (
FROM) - Install dependencies (
RUN) - Copy in source code (
COPY) - Configure the final image (such as
CMD, the default command a container runs)
Common instructions also include:
WORKDIR, the directory where later commands runENV, environment variablesEXPOSE, the port an image wants exposedUSER, the default user for later instructions
A registry is "a centralized location for storing and sharing your container images." A repository is a related collection of images inside a registry.
Docker Hub is the default public registry. Other registries exist too, including AWS Elastic Container Registry, Azure Container Registry, and Google Artifact Registry. Self-hosted options include Harbor, JFrog Artifactory, and GitLab Container Registry.
Pulling or running an image fetches it from the configured registry, and pushing an image uploads it there.
Containers vs. virtual machines
A virtual machine is an entire separate operating system, complete with its own kernel. It runs on top of your real machine. A container is much lighter, just an isolated process that shares the host machine's kernel with other containers.
Running ten containers on one server shares that server's single kernel among all ten. Running ten virtual machines on the same server means ten separate operating systems, each with its own kernel. All of them compete for the same hardware.
The technical details
Docker's own docs put it plainly.
"A VM is an entire operating system with its own kernel, hardware drivers, programs, and applications. Spinning up a VM only to isolate a single application is a lot of overhead. A container is simply an isolated process with all of the files it needs to run. If you run multiple containers, they all share the same kernel, allowing you to run more applications on less infrastructure."
Docker's docs also note that containers and VMs are often combined in the cloud. A cloud provider typically provisions VMs. A container runtime running inside one VM can then host multiple containerized applications, increasing resource use and reducing cost compared to one VM per application.
Going deeper
How does the docker command build and run things?
Docker uses a client-server architecture. The docker command you type is a client, and it talks to a separate background process called the Docker daemon, which does the real work.
Client, daemon, and the API between them
The Docker daemon, dockerd, is a long-running process that listens for requests. It does the real building, running, and distributing of containers. The docker command-line client sends instructions to the daemon rather than performing them itself.
They communicate over the Docker REST API, either through Unix sockets or a network interface. This lets the client and daemon run on the same machine, or the client connect to a daemon running remotely.
Docker's own docs describe it directly. "The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers."
What this makes possible
Because the daemon exposes an API rather than only a command line, other tools can be built on top of it. Docker Compose, for managing multi-container applications, is one such client that uses this same API.
Docker Desktop is the packaged application for Mac, Windows, and Linux. It bundles the daemon, the CLI client, Compose, Docker Content Trust, Kubernetes, and a credential helper into one install. Docker Engine, the open-source core of this architecture, is licensed under Apache License 2.0.
What isolates one container from another?
Containers feel like separate machines, but they are processes on the same machine, kept apart by features built into the Linux kernel itself.
Namespaces separate what each container can see
Docker's own docs name the mechanism directly. "Docker uses a technology called namespaces to provide the isolated workspace called the container... Each aspect of a container runs in a separate namespace and its access is limited to that namespace." Wikipedia's independent account of Docker names the specific namespace types the kernel provides.
- Process trees
- Network
- User IDs
- Mounted filesystems
Each of these can be walled off per container. A container's own view of running processes, network interfaces, and files stays separate from the host and from other containers.
cgroups limit what each container can use
Namespaces control visibility. Something else has to stop one container from consuming all of a machine's CPU or memory.
That job belongs to a separate Linux kernel feature called cgroups (control groups), which provides resource limiting for memory and CPU. Docker's own beginner docs describe namespaces but do not name cgroups directly. This detail comes from Wikipedia's independent, more technical description of the same underlying mechanism.
Why this makes containers lighter than virtual machines
Containers share the host's single kernel rather than each running their own. That means far less overhead than virtual machines, which is the basis for the containers-vs-VMs comparison above.
A 2018 analysis cited by Wikipedia found that a typical Docker use case involves running eight containers on a single host. A quarter of the organizations studied ran 18 or more containers per host.
How does Docker keep images small and fast to rebuild?
Images are built from stacked, reusable layers rather than as one solid block. That is what lets Docker avoid rebuilding an entire image every time something small changes.
Each instruction becomes a layer
Per Docker's own docs, "images are composed of layers," and "each layer represents a set of file system changes that add, remove, or modify files."
Each instruction in a Dockerfile creates one of these layers. When you change the Dockerfile and rebuild, only the layers affected by that change need to be rebuilt. That is part of what keeps images lightweight, small, and fast to work with compared to older virtualization approaches.
The filesystem technology underneath
On Linux, this layering is implemented using what Wikipedia describes as "a union-capable file system (such as OverlayFS)."
A union filesystem can present several separate layers of files as if they were one combined filesystem. That is what lets a container add a thin, writable layer on top of a shared, read-only image, without duplicating everything underneath it.
Docker's own image documentation confirms the layering and immutability principles but does not name OverlayFS specifically. That detail comes from Wikipedia's independent, more technical account.
As a concrete sense of scale, Docker's own tutorial image, docker/welcome-to-docker, is approximately 29.7MB uncompressed, built from a small number of these layers.
What is Docker built on, under the hood?
Docker itself is a piece of software with its own implementation history, separate from the Linux kernel features it relies on.
Written in Go, and a change in how it runs containers
Docker is written in the Go programming language. When it first launched in 2013, it used an existing tool called LXC (Linux Containers) as its default execution environment.
A year later, with version 0.9 in 2014, Docker replaced LXC with its own component, called libcontainer. Also written in Go, it talks to the Linux kernel's virtualization features more directly.
Both Docker's own docs and Wikipedia's independent account agree on this history. Docker is written in Go, and it has used libcontainer instead of LXC as its default execution driver since 2014.
What does Docker cost?
Docker's paid plans are billed per user per month, with a free tier for individuals and small projects. Prices below are annual/monthly, as listed on Docker's own pricing page.
- Docker Personal: $0. Includes Docker Desktop, Docker Engine plus Kubernetes, Docker Hub, Docker Scout, and Docker Debug, for 1 user. Limits are 1 Docker Scout-enabled repo, 100 Docker Hub pulls per hour, and 1 private Docker Hub repo (unlimited public repos).
- Docker Pro: $9/user/month billed annually, or $11/user/month billed monthly. Adds Docker Build Cloud, Testcontainers Cloud, Synchronized File Shares, and Docker Scout health scores. Limits are an unlimited Hub pull rate, 200 Build Cloud minutes a month, and 100 Testcontainers Cloud minutes a month.
- Docker Team (Docker's "Most Popular" tier): $15/user/month billed annually, or $16/user/month billed monthly. Supports up to 100 users, with unlimited Scout-enabled repos, unlimited private Hub repos, 500 Build Cloud minutes, and 500 Testcontainers Cloud minutes a month.
- Docker Business: $24/user/month, contact sales, invoice billing available. No user cap, 1,500 Build Cloud and 1,500 Testcontainers Cloud minutes a month, plus SSO, SCIM, and unlimited Hub organizations.
A separate track for Docker Hardened Images
Docker also sells a separate line of pre-hardened, low-vulnerability images called Docker Hardened Images (DHI), priced apart from the plans above.
- A free Community tier
- A Select tier starting at $5,000 per repository
- A contact-us Enterprise tier
A carve-out for small companies
Companies with fewer than 250 employees and less than $10 million in annual revenue can use Docker Desktop standalone for free. So can non-commercial open source projects, according to both Docker's pricing FAQ and its Docker Engine documentation. Docker's Engine itself, the open-source core, remains free and is supported by the Moby project community regardless of company size.
Sources
- What is Docker? (Docker Docs)
- What is a container? (Docker Docs)
- What is an image? (Docker Docs)
- What is a registry? (Docker Docs)
- Writing a Dockerfile (Docker Docs)
- Docker Engine (Docker Docs)
- Docker Hub product page (Docker)
- Pricing (Docker)
- Docker Plans FAQs (Docker)
- Docker (software), Wikipedia
Last checked August 2026