Container and Docker have been hot topic in the recent years. Today, it is unthinkable to start a new project without "dockerizing" it. But what exactly is a container? And why is so useful? Let's try to answer these and others question on this text.

A container is a form of virtualization. By virtualization you can think of a way to use a computer's resources more efficiently. There are two types of virtualization. The first one is to emulate a full Operational System (a Virtual Machine, VM), using a hypervisor. There are a lot of details on this topic, because the hypervisor can be either type 1 (bare metal) or type 2, for example. Examples of these type of virtualization are VirtualBox, from Oracle, or Xen. This is a well established solution, as this has been developing since the 1970s. However, as a new layer is introduced (the hypervisor), there is a small overhead on the overall performance.

The second type of virtualization is the container, also known as lightweight virtualization. Using containers, we remove the need of having an hypervisor. Each process runs on the same OS. The resources are limited by the host Operational Systems, using tools like Linux namespaces and Linux Control Groups. With these, a container cannot see another container's info, isolating it.

And how is the performance of a container, when compared to hypervisor virtualization? Studies that compared the performance of a Cassandra database on a non-virtualized environment, a Docker (container) and a Hypervisor virtualization, show that the performance of the container is almost similar to running it bare-metal (non-virtualized), being the Hypervisor the slowest on this scenario.

Today, although Docker is the most known container runtime, it is not the only one. For example, you can use podman or containerd to run containers. And how exactly do you execute a container? Using Images. An image is a template, it tells the container runtime (Docker, for example) what to execute. Also, the advantage of an image is that it is made of layers. Each instruction is stored as a layer. With this, if two containers use the same layer, it can be reused, avoiding downloading them twice. Only the layer that differs will be downloaded. You can declare an image using a Dockerfile.

Despite the name of the file, you don't have to have Docker to execute this Dockerfile. There is an association, the Open Container Initiative (OCI), who defines standards to be adopted by the industry. And one of these standards is about images. There is a specification on how the images should be made, and Docker supports it. So, using a Dockerfile enables you to use any other container runtime, as long as they follow the spec.

Now that we know what a container is, you may be asking yourself what is the greatest advantage to the developer. In our opinion, it is having the possibility to have the same environment that will run in production. For example, if you need a specific version of your language, like PHP 8.1, you can declare it on the Dockerfile. Assuming that your production will also run in a container, you can avoid errors of testing in one version of the language and deploying it in another. Another advantage is that you can run your dependencies as a container too. For example, there are images for Redis and PostgreSQL. Using those images, you can start your dependencies whenever you need, without even having to install it on your machine. A very practical way to develop.

If you liked the idea of running your applications using containers, and you don't know where to start, there is plenty of documentation online. A good way to start is reading the Docker docs, or, if you prefer, you can watch YouTube tutorials.

Written by Rodrigo Müller