Docker containers provide a similar service to virtual machines, providing an isolated environment for running applications, but they are basically two different technologies. We’ll discuss the differences and what makes Docker so useful.
What makes Docker so useful?
The main purpose of a virtual machine is to partition a large server into smaller pieces. The important thing is that it isolates the running processes on each virtual machine. For example, your hosting provider might have a 32-core machine and split it into eight 4-core VMs that they sell to different customers. This cuts costs for everyone, and they’re great if you run a lot of processes or need full SSH access to the underlying hardware.
However, if you are running only one application, you might be using more resources than you need to. To run this single application, the hypervisor must be running an entire guest operating system, which means the 32-core machine is running eight copies of Ubuntu. On top of that, you have virtual machine overhead for each instance.
Docker presents a better solution. Docker containers provide isolation without the overhead of virtual machines. Each container operates in its own environment, sectioned with Linux namespaces, but the important part is that the code in the containers runs directly on the machine. No emulation or virtualization is involved.
There is still a bit of overhead due to networking and interfacing with the host system, but Docker applications generally run at speeds close to the speed without an OS, and certainly much faster. than your average VPS. You don’t have to run 8 copies of Ubuntu, just one, which makes it inexpensive to run multiple Docker containers on a host. Services like those from AWS Elastic container service and GCP Cloud Run provide a means to run individual containers without provisioning an underlying server.
Containers are all of the dependencies that your application needs to run, including libraries and binaries used by the operating system. You can run a CentOS container on an Ubuntu server; they both use the linux kernel, and the only difference is the binaries and libraries included for the operating system.
The main difference with Docker containers is that you generally won’t have SSH access to the container. However, you don’t exactly need it: the configuration is completely handled by the container file itself, and if you want to make updates, you will have to push a new version of the container.
Since this setup takes place entirely in code, it allows you to use version control like Git for your server software. Since your container is a single image, it’s easy to track the different versions of your container. With Docker, your development environment will be exactly the same as your production environment, and also the same as everyone else’s development environment, which will alleviate the problem of “it’s broken on my machine!”
If you want to add another server to your cluster, you don’t have to worry about reconfiguring that server and reinstalling all the dependencies you need. Once you have created a container, you can easily launch a hundred instances of that container, without much configuration. It also allows Very easy autoscaling, which can save you a lot of money.
Disadvantages of Docker
Of course, Docker isn’t replacing virtual machines anytime soon. They are two different technologies, and virtual machines still have many advantages.
Networking is generally more involved. In a virtual machine, you typically have dedicated network hardware exposed directly to you. You can easily configure firewalls, configure applications to listen on certain ports, and run complex workloads like load balancing with HAProxy. On Docker, because all the containers are running on the same host, it is often a bit more complicated. However, container-specific services like AWS Elastic Container Service and GCP’s Cloud Run will typically provide this network as part of their service.
Performance on non-native operating systems is always comparable to that of virtual machines. You cannot run a Linux container on a Windows host machine, which is why Docker for Windows actually uses a Linux virtual machine Windows subsystem to manage running containers. Docker essentially provides a layer of abstraction on top of the virtual machine in this case.
Persistent data is also a bit complicated. Docker containers are designed to be stateless. This can be solved with volume mounts, which mount a directory on the host on the container, and services like ECS allow you to mount shared volumes. However, it’s not worth storing data on a normal server, and you wouldn’t really want to try and run a production database in Docker.