For several months now, I've been using Docker to streamline the development and delivery process of web projects. I offer readers of 'Habrhabr' a translation of the introductory article about Docker - .
What is Docker?
Docker is an open platform for developing, delivering, and running applications. Docker is designed for faster deployment of your applications. With Docker, you can separate your application from your infrastructure and treat your infrastructure as a managed application. Docker helps you deploy your code faster, test more quickly, release applications sooner, and reduce the time between writing and running code. Docker achieves this through a lightweight container virtualization platform that utilizes processes and tools to help manage and deploy your applications.
At its core, Docker allows you to run almost any application securely isolated in a container. This secure isolation lets you run multiple containers simultaneously on a single host. The lightweight nature of the container, which runs without the overhead of a hypervisor, allows you to get more out of your hardware.
The platform and tools for container virtualization can be beneficial in the following scenarios:
- packaging your application (and its components) into Docker containers;
- distributing and delivering these containers to your teams for development and testing;
- deploying these containers to your production environments, both in data centers and in the cloud.
What can I use Docker for?
Rapid deployment of your applications
Docker is perfect for organizing the development cycle. It allows developers to use local containers with applications and services, which can then be integrated into the continuous integration and deployment workflow.
For example, your developers write code locally and share their development stack (a set of Docker images) with colleagues. When they are ready, they send the code and containers to a test environment and run any necessary tests. From the test environment, they can push the code and images to production.
Simplified deployment and rollout
The container-based Docker platform makes it easy to port your workload. Docker containers can run on your local machine, both on physical and virtual machines in the data center, as well as in the cloud.
The portability and lightweight nature of Docker allows for easy dynamic management of your workload. You can use Docker to deploy or scale down your application or services. Docker's speed enables this to be done nearly in real-time.
High loads and larger payloads
Docker is lightweight and fast. It provides a robust, cost-effective alternative to hypervisor-based virtual machines. It is particularly useful in high-load conditions, such as when creating your own cloud or platform-as-a-service (PaaS). However, it is also beneficial for small and medium applications when you want to get the most out of your available resources.
Main Components of Docker
Docker consists of two main components:
- Docker: an open-source virtualization platform;
- Docker Hub: our platform-as-a-service for distributing and managing Docker containers.
Note! Docker is distributed under the Apache 2.0 license.
Docker Architecture
Docker uses a client-server architecture. The Docker client communicates with the Docker daemon, which handles the heavy lifting of creating, running, and managing your containers. Both the client and server can operate on the same system, and you can connect the client to a remote Docker daemon. The client and server communicate via a socket or through a RESTful API.

Docker Daemon
As shown in the diagram, the daemon runs on the host machine. The user does not interact directly with the server, but does so through the client.
Docker Client
The Docker client, the Docker program, is the main interface to Docker. It receives commands from the user and interacts with the Docker daemon.
Inside Docker
To understand what makes up Docker, you need to know about three components:
- images
- registries
- containers
Images
A Docker image is a read-only template. For example, an image may contain the Ubuntu operating system with Apache and an application running on it. Images are used to create containers. Docker makes it easy to create new images, update existing ones, or download images created by others. Images are a component of Docker's architecture.
Registry
A Docker registry stores images. There are public and private registries from which you can download or upload images. The public Docker registry is . It holds a vast collection of images. As you know, images can be created by you or reused from those made by others. Registries are a component of distribution.
Containers
Containers are like directories. Containers contain everything needed for an application to run. Each container is created from an image. Containers can be created, started, stopped, moved, or deleted. Each container is isolated and provides a secure platform for the application. Containers are a component of operation.
So, how does Docker work?
So far, we know that:
- we can create images that contain our applications;
- we can create containers from images to run applications;
- we can distribute images via Docker Hub or another image registry.
Letās see how these components fit together.
How does an image work?
We already know that an image is a read-only template from which a container is created. Each image consists of a set of layers. Docker uses to combine these layers into a single image. The union file system allows files and directories from different file systems (different branches) to seamlessly overlay, creating a coherent file system.
One of the reasons Docker is lightweight is its use of such layers. When you modify an image, for example, by updating an application, a new layer is created. Therefore, without replacing or rebuilding the entire image as you might need to do with a virtual machine, only the layer is added or updated. And you donāt need to distribute the entire new image; only the update is shared, making image distribution simpler and faster.
Each image is based on a base image. For example, ubuntu, the base image of Ubuntu, or fedora, the base image of the Fedora distribution. You can also use images as a foundation for creating new images. For instance, if you have an apache image, you can use it as the base image for your web applications.
Note! Docker typically pulls images from the Docker Hub registry.
Docker images can be created from these base images; the steps to create these images are referred to as instructions. Each instruction creates a new image or layer. The instructions include the following actions:
- running a command
- adding a file or directory
- creating an environment variable
- specifying what to run when the container of this image starts
These instructions are stored in a file Dockerfile. Docker reads this Dockerfile, when building the image, executes these instructions, and returns the final image.
How does the Docker registry work?
A registry is a repository for Docker images. After creating an image, you can publish it to the public Docker Hub registry or your personal registry.
With the Docker client, you can search for already published images and download them to your machine with Docker to create containers.
Docker Hub provides public and private repositories for images. Searching and downloading images from public repositories is available to everyone. The contents of private repositories do not appear in search results. Only you and your users can access these images and create containers from them.
How does a container work?
A container consists of an operating system, user files, and metadata. As we know, each container is created from an image. This image tells Docker what is inside the container, which process to run when the container starts, and other configuration data. A Docker image is read-only. When Docker starts a container, it creates a read/write layer on top of the image (using the union file system, as previously mentioned), where an application can be run.
What happens when a container is started?
Either through a program docker, or via the RESTful API, the Docker client tells the Docker daemon to start the container.
$ sudo docker run -i -t ubuntu /bin/bash
Let's break down this command. The client is started with the command docker, with the option run, which indicates that a new container will be started. The minimum requirements for starting a container are as follows:
- which image to use for creating the container. In our case,
ubuntu - the command you want to run when the container starts. In our case,
/bin/bash
What happens under the hood when we run this command?
Docker sequentially does the following:
- downloads the ubuntu image: docker checks for the image
ubuntuon the local machine, and if it's not there, downloads it from . If the image exists, it uses it to create the container; - creates the container: when the image is obtained, docker uses it to create the container;
- initializes the file system and mounts the read-only layer: the container is created in the file system and the read-only layer is added to the image;
- initializes the network/bridge: creates a network interface that allows docker to communicate with the host machine;
- Sets the IP address: finds and assigns the address;
- Starts the specified process: runs your application;
- Processes and outputs your application's output: connects to and logs the standard input, output, and error stream of your application, allowing you to monitor how your application operates.
Now you have a working container. You can manage your container and interact with your application. When you decide to stop the application, remove the container.
Technologies used
Docker is written in Go and utilizes certain capabilities of the Linux kernel to implement the functionality described above.
Namespaces
Docker employs the namespaces technology to organize isolated workspaces, which we call containers. When we start a container, docker creates a set of namespaces for that container.
This creates an isolated layer, where each aspect of the container runs in its own namespace and has no access to the external system.
Here is a list of some namespaces used by docker:
- pid: for process isolation;
- net: for managing network interfaces;
- ipc: for managing IPC resources. (IPC: InterProcess Communication);
- mnt: for managing mount points;
- utc: for isolating the kernel and controlling versioning (UTC: Unix timesharing system).
Control groups
Docker also uses the technology cgroups or control groups. The key to the application's operation in isolation is providing it with only the resources you want to allocate. This ensures that containers will be good neighbors. Control groups allow you to segregate available hardware resources and, if necessary, set limits and constraints. For example, you can limit the possible amount of memory for a container.
Union File System
Union File System or UnionFS is a file system that operates by creating layers, making it very lightweight and fast. Docker uses UnionFS to create the layers from which containers are built. Docker can use several types of UnionFS including: AUFS, btrfs, vfs, and DeviceMapper.
Container Formats
Docker combines these components into a wrapper that we call the container format. The default format used is called libcontainer. Docker also supports the traditional container format in Linux via . In the future, Docker may support other container formats, for example, by integrating with BSD Jails or Solaris Zones.
Source: habr.com
