Should you be like me, meaning you don’t work with docker daily, but still realize it could be useful for your personal projects. These notes should give enough context to make you dangerous.
What is containerization
Its a method for ensuring that an application is run in the exact environment it was intended for. Basically instead of shipping an application, you are shipping an application plus operating system (minus the kernel). The benefit is that by defining the container you can ensure that the environment is set up exactly in the way the app expects. Thus avoiding the old “works on my machine” issue.
Under the hood
Linux kernel provides two significant features:
- namespaces - You can change how a process sees the host. Meaning you can provide whole new filesystem structure (among others). Perhaps hiding most of your hosts files (incl. directories). You can still expose some files, but under a different location if you wish, etc. As you can see its huge step in making your tool think its in its own personal environment.
- cgroups - Controls how much resources a process can use (CPU, memory, disk, etc.). Not highly relevant for small experiments, but important in understanding how the underlying hardware use would be managed.
And thats pretty much it, with this, on Linux, you can make a process think they are in a separate environment, and you can provide them the exact dependencies they need. While hiding access to your host to mess it up.
But docker images have Linux distros included?
That is correct. It could imply that Docker runs a Linux Virtual Machine with that distro. Sounds heavy and slow, luckily this is not the case. The key here is that Linux kernel is a separate component in any Linux distro. And the kernel has a very well defined and established interface. Therefore the distro in the container can rely on the very same kernel that is running the host. Docker images do not contain a kernel!
Just like with namespaces, docker will replace the whole root filesystem with the one from the particular Linux distro.
What if im on a Mac?
This is a problem. Since the kernels on Mac or Windows are not compatible with Linux. The workaround is that now Docker does actually run a Virtual Machine (VM) with Linux on your host. And then any containers can be established in that VM. This of course has some performance overhead compared to running docker on Linux natively.
Glossary
- Dockerfile - is the blueprint for the environment. Its just a text file that only contains the build instructions. Based on that docker will build the actual image. The instructions generally are specifying a base image (linux distro, usually with some extra packages already installed). Some commands to set up the desired environment: install more packages, configure them. Perhaps copy some files from host to the image, etc.
- Docker image - Is the actual file that gets built based on Dockerfile instructions. Basically the linux system snapshot with the changes specified in Dockerfile applied to it. Somewhat like an .iso file - a packaged source for the environment that you can share.
- Container - Actual running instance of the image. You can have many instances of same image.
- docker-compose.yml - Specifies the run configuration of the container. Basically the things the host is concerned with, which port to give to container, which folder from host should be mapped to container, etc. You can skip it if you like specifying all the flags manually for
docker run
command. - docker compose - Tool that reads docker-compose.yml. Besides doing the setup for run, it can also build image if it hasn’t been built. Basically reduces interactions with docker down to
docker compose up
anddocker compose down
. It’s worth knowing its main purpose is orchestrating multi-container applications.