There are quite a few terms that get thrown around in the Docker community. Even the word Docker has a (slightly hidden) meaning. In Docker Deep Dive Nigel Poulton explains that "the word 'Docker' comes from a British colloquialism meaning dock work_er_ - somebody who loads and unloads cargo ships."
While you can use Docker without knowing where its name originated from, it is important that you know the jargon. To that end, this blog post will show you the main terms in the Docker world along with their meaning.
If you’re new to Docker or have always wanted a more thorough explanation, this post is for you. You do not need any special knowledge to follow along. After reading this post you will know the meaning of the following terms:
- Docker Container
- Docker Image
- Docker Volumes
- Docker Engine
- Image Registries
Docker markets itself as a container platform that helps developers build, ship, and run any application in any environment. Apps written on your computer will run the exact same way on your friend's computer, a bare metal server, the cloud, etc. That includes hosts with different operating systems such as Windows and Mac computers. To run Linux containers on both of these, Docker uses a light-weight Linux VM that operates on top of a hypervisor (xhyve for Mac and Hyper-V or VirtualBox for Windows).
You can look at the benefits of Docker from the perspective of two groups of people: DevOps folks, and developers. If you're a developer, the benefit of Docker is that you can set up one environment which you can use for both testing and for production. Iterating on, testing, and deploying changes should be very fast. On top of that, containers solve the problem of 'it works for me'-bugs because everything will be exactly the same regardless where you deploy. If you do DevOps, containers allow you to focus more on container management while removing the responsibility of configuring machines. Now that you know about Docker, the next step are Docker containers.
A container packages code and dependencies together to create a light-weight, abstracted, portable app. Containerizing apps allows you to maximise the utilization of a machine's resources by allowing you to run many apps. Each container is run in its own isolated environment. Docker containers are created on top of Docker Images.
A Docker Image can be thought of as a blueprint of an application. It's important to understand the difference between images and containers: An image is not the same as a running container - it's merely a snapshot of a container. Given such a snapshot the Docker engine knows how to create a container when a
docker run command is issued but the snapshot itself is only a lifeless read-only blueprint.
To build such a snapshot, you use a Dockerfile, i.e. a file on disk that contains instructions for creating an image. When you issue a
docker build command, Docker uses a base image (e.g. a centos image or a ubuntu image). On top of the base image Docker executes each instruction within the Dockerfile to produce a new Docker Image. The file changes that occur when each instruction is executed are stored as a read-only filesystem, also called a layer. Most images consist of multiple layers (one for each line of instructions from the Dockerfile that was used to create the image). Since all layers are read-only the Docker Image is immutable.
When a container is run, the Docker engine, in particular its storage engine, takes care of presenting the layers that form an image as a single unified object (somewhat similar to git commits). On top of this unified object, the Docker engine (in particular its storage driver) then adds a read-write filesystem which makes it an actual container. Any file changes that occur happen inside this top layer which is the only layer that can be modified when a container is run. This setup makes containers very resource-efficient, as multiple containers can be run using the same image.
The read-writable layer on top of the image within a container is meant to be thin and is not designed to hold persistent data. If you do need to have persistent data, then Docker suggests to use Docker Volumes. Volumes are independent constructs that can be attached to containers. If a container is killed or dies, the volume will still be accessible even if the container is removed. With containers you generally shouldn't care about them dying or being killed, because they are not special and you can easily create new ones. Tools like Kubernetes allow you to automatically spin up new containers should anything happen to the running ones.
Containers, Images, and Volumes are all managed by the Docker Engine which needs to be installed on top of an operating system. The Docker Engine is a client-server application made up of the Docker daemon, a REST API that specifies interfaces for interacting with the daemon, and a command line interface (CLI). When you issue a Docker command on the commandline, the Docker CLI will use the daemon's REST API to communicate with the daemon. The daemon will in turn work with with the host operating system to allocate operating system resources (CPU, storage, etc) for containers.
The last thing to mention are Image Registries like Docker Hub, Google Container Registry, and Azure Container Registry. These fulfill a similar function GitHub fulfills for code: they host Docker images which can be used by yourself and others. Docker Hub has a library full of official images like this MongoDB image. You can use these official images as base images for your own images. If you would like to look at the Dockerfiles that were used to create the official images, you can find the links to them on the pages of the official images. It's also possible to host your own private registry of images.
This concludes our overview of Docker Jargon. If you are interested to learn more, check out: