DEV Community

Cover image for How Docker Works Internally
coder7475
coder7475

Posted on • Edited on

How Docker Works Internally

Docker has changed how we build, ship, and deploy applications by offering lightweight, portable, and fast containers.

But what makes Docker work under the hood?

In this blog, we’ll dive into Docker’s architecture and the Linux technologies that power it.

📖 New to Docker? Check out the Introduction to Docker to understand the basics before diving into internals.


⚙️ The Underlying Technology

Docker is written in Go, a modern systems programming language known for its speed and concurrency support.

At its core, Docker Engine uses several Linux kernel features to deliver containerization:

  • Linux Containers (LXC)
  • Control Groups (cgroups)
  • Union File Systems (UnionFS)
  • Namespaces

Docker’s architecture is conceptually similar to LXC but adds tooling, APIs, and image management, making containers easier to use for developers.


⚙️ The Underlying Technology

Docker is written in Go, a modern systems programming language known for its speed and concurrency support.

At its core, Docker Engine uses several Linux kernel features to deliver containerization:

  • Linux Containers (LXC)
  • Control Groups (cgroups)
  • Union File Systems (UnionFS)
  • Namespaces

Docker’s architecture is conceptually similar to LXC but adds tooling, APIs, and image management, making containers easier to use for developers.


🧩 Linux Technologies that Power Docker

📦 LXC (Linux Containers)

LXC allows multiple isolated Linux systems to run on a single host:

  • Containers share the host’s kernel but operate in isolated user spaces.
  • They start quickly because they don’t boot an entire OS.
  • Useful for running applications, testing software, or deploying services in the cloud.
  • With tools to create, monitor, and manage containers, LXC provides the foundation for lightweight virtualization.

Docker initially used LXC and later built its own runtime (libcontainer) for more flexibility and control.


🛡 Namespaces: Process Isolation

Namespaces ensure containers don’t interfere with the host or each other by providing isolated views of system resources:

Namespace Isolates
pid Process IDs
net Network interfaces and routing tables
mnt Mount points and filesystems
uts Hostname and domain name
ipc Inter-process communication
user User and group IDs

Example: Processes inside a container only see their own processes because of the pid namespace.


⚙️ Control Groups (cgroups): Resource Control

cgroups is a Linux kernel feature that allows:

  • Limiting CPU, memory, disk I/O, and network usage per container.
  • Tracking and monitoring resource consumption.
  • Preventing a single container from exhausting the host’s resources.

This makes multi-tenant environments predictable and stable.


🗂 Union File Systems (UnionFS): Efficient Storage

Docker images use Union File Systems (like OverlayFS, AUFS, or Btrfs) to implement layers.

  • Each instruction in a Dockerfile (like RUN, COPY) creates a new layer.
  • When running a container, Docker adds a thin, writable layer on top.
  • Changes inside the container only affect the writable layer.
  • Layers are shared across images, saving disk space and bandwidth.

Example: Multiple containers can share the same Ubuntu base image while having their own unique changes.


🌐 Docker Networking

Docker configures different network drivers to enable communication inside and outside containers:

Network Type Use Case
bridge Default for single-host; containers share a virtual bridge
host Container shares host’s network stack (no isolation)
overlay Multi-host networks for Docker Swarm / Kubernetes
macvlan Assigns a MAC address to containers, appearing on LAN

When you run:

docker run -d -p 8080:80 nginx
Enter fullscreen mode Exit fullscreen mode

Docker:

  • Connects the container to the bridge network.
  • Configures NAT to forward traffic from port 8080 on the host to port 80 inside the container.

🧪 Putting it All Together

Here’s what happens step by step when you run:

docker run -d -p 8080:80 nginx
Enter fullscreen mode Exit fullscreen mode

✅ Docker:

  1. Reads the image (built from UFS layers)
  2. Creates a new container layer (writable)
  3. Applies namespaces for isolation
  4. Applies cgroups for resource limits
  5. Sets up networking to connect to the host and the world

All this happens in seconds, which explains why containers start so quickly compared to virtual machines.


🛠 Extra: Exploring Docker Internals

Try these commands to peek inside:

# See cgroups hierarchy
ls /sys/fs/cgroup

# List running processes in a container
docker top <container_id>

# Inspect full container metadata
docker inspect <container_id>

# See filesystem changes in a container
docker diff <container_id>
Enter fullscreen mode Exit fullscreen mode

✅ Conclusion

Docker isn’t magic — it stands on the shoulders of decades of Linux innovation:

  • Namespaces for process isolation
  • cgroups for resource management
  • UnionFS for layered, efficient storage
  • LXC as an inspiration for containerization
  • Networking drivers to connect containers seamlessly

By combining these with a developer-friendly API, Docker made containers practical, portable, and production-ready.

From the kernel to the cloud, Docker brings it all together for modern apps!


📚 Further Reading


🧰 Next Up: Installing Docker on Ubuntu

In the next post, we’ll walk through how to install Docker on Ubuntu step by step — from setting up the repository to verifying your installation and running your first container.

Stay tuned!

Top comments (0)