Container images are key to containerization. But what’s inside them? And how do they work? Read our guide to what’s in a container image to find out.
Lois Neville
Marketing
In our series on containerization, we’ve delved into the technology, discussed its advantages, and even explored the tools you can use. But let’s get right back to basics and take a look at what containers are actually built from. Container images are the building blocks of containerization. They are key to running these applications, in that they include information needed for these applications to run. But how are they made, what’s inside them, and how do they actually work?
This article has been written for individuals new to containerization, as well as those who want to brush up on their knowledge.
We’ll be going through:
Image vs. Container: What’s the Difference?
What is a Container Image?
What Comprises a Container Image?
Docker Image vs. Container: What’s the Difference?
How to Start Container From a Image in Docker
How to Save Container From an Image in Docker
Key Container Image Concepts
Takeaways
Whilst intrinsically linked, containers and container images are two different things.
An image is a template that packages together the dependencies needed to run an app - we’ll get into what these exactly are in a bit.
A container is a running instance of an image that can execute applications on its own data and state.
Simply put, an image can exist without a container, but a container can’t exist without an image.
You may see the terms ‘image’ and ‘container image’ used simultaneously. In this context, these terms both mean the same thing. A container image, as mentioned above, contains everything needed to run a containerized application. It’s a type of template, and it is static and immutable. This means that once the image has been built, what’s inside cannot be changed. The code it contains is a packaged application including the application’s dependencies, configuration files, and environment variables.
You may see the term ‘Docker image’ being used too. A container image created using Docker is called a Docker image. Docker is a popular container tool and has been part of the driving force behind the adoption of container technology. As such, it’s worth looking into Docker images too. You may see ‘container image’ and ‘Docker image’ being used interchangeably. They’re not exactly the same thing, but very alike.
Similar to a container image, a Docker image is also an unchangeable template. It’s also read only. It also contains instructions - all of the essential information - for creating, configuring and running containers on Docker. This includes dependencies, application code, and installation information.
Now we’ve discussed what containers and Docker images are, let’s take a look at what is actually inside them.
A container image is composed of layers - a bit like how a painting is built up of layers of paint. The layers are added to the base image. One of the advantages of this layered system is that different layers can be used across other images too. Constructing a container image using an optimised layering format can be an additional way to reduce the size of a container and make it run even faster.
Let’s take a closer look at the different layers that make up a container image, and some of the terminology that is used.
Parent Image. If a user is creating a new container image based on a pre-existing image, the image used as the foundation is called the parent image. Parent images are specified using the FROM directive at the beginning of a Dockerfile. If a user is building a container image from scratch then there is no parent image.
Base Image/Layer. Base images are those without a parent, specifically those which specify the directive FROM scratch. They are often used as parent images for other images which inherit from them. Base images frequently correspond to barebones operating systems such as debian:10 or ubuntu:16.04.
Container Layer. This is the current, writable layer. If any changes are to be made on top of preceding layers, this is where they happen. This can include the modification, addition, or deletion of files.
Overlay. Images save space by using the overlay drivers of the underlying union filesystem. When a child image is created from a parent image, instead of copying over everything from the parent image, the child’s filesystem is mounted onto the parent’s. In this way, the child can access the parent’s directories without the need for copying.
Diff layer. This is where any changes made in the mounted overlay layer are stored.
Now that we’ve covered what a container image is, let’s circle back and take a closer look at Docker images.
Just like comparing a container image to a container, Docker image vs. container is not comparing like-for-like. Docker images and Docker containers are different parts of the same system that have different objectives. In this instance, a Docker image, like a container image, is a template file that contains the information and files needed to deploy and run a containerized application on Docker. A Docker container, on the other hand, is a containerized application in action. This is known as a runtime instance of a Docker image.
As mentioned, a Docker image is a type of container image that can be used on the Docker system. Like container images, a Docker image:
Is immutable and unchangeable.
Contains dependencies, tools, libraries, and code needed to run the application.
Is read-only.
Let’s take a look at the layers in a Docker image:
Parent Image. As with a general container image, Docker images can have parent images too from which they inherit.
Base Image. Again, base images for Docker images allow users to build images themselves from scratch. This option is suitable for those experienced with using Docker and allows for a greater level of customisation.
Image Layers. Again, the image changes built on top of the base/parent image are called image layers. The hierarchy a user slots them into is important as each layer is dependent on the layers below them. It’s considered best practice to organise these layers based on how often they change, with those that change the most frequently nearest the top. This is because any changes made to a layer propagate to the layers above it.
Container Layer. This one is a little different. Basically, every time a container is launched in Docker from an image, a very small, writable layer is added. This is called a container layer. This layer collects and stores any changes that were made to the container whilst it was running. This is very useful, as similar containers may be given access to this information, and apply it to themselves. This can improve efficiency and speed!
Docker Manifest. This is distinct to the Docker image. It’s an additional file that contains information about the image as JSON, such as its size, layers, and digest. This can be useful if users want to configure a container to run on a different platform.
Now that we’ve covered Docker images, let’s take a quick look at what a Docker container is.
Like a general container, a Docker container is a virtual environment where Docker images are run. This is known as a runtime environment. Docker containers operate autonomously on the Docker Engine. Docker images require this type of environment to actually operate. A Docker container is essentially an image that is running. Once this is in progress, a container layer is created. This means users are now able to modify the container, using the container layer to write changes to the filesystem.
Let’s now take a quick look at how Docker images are created.
There are two ways that a user can create a Docker image.
Option one uses a Dockerfile, which is a special type of script. This method involves using Docker to create a container from an image. This is based on creating a plain-text file that includes all of the requirements needed to create a Docker image. Think of this as a set of instructions and commands that defines everything needed for an application to run. It includes code, dependencies, files, binary libraries, and more. The image created from the Dockerfile can then be used as the base layer, or a template. This can all be done on the Docker interface using docker create.
Option two for making a Docker image involves creating an image from a container. This involves running a container from a pre-existing image, and then manually changing the container layer while the container is running. You can then save the new, modified state that has been created as a Docker image. This is done using the docker commit command. The user can then build new layers on top of this if they wish.
Along with knowing the differences between images and containers, to fully understand how they work, there are some key concepts and technologies that need to be explored. Let’s take a look at some of them.
This technology goes all the way back to Linux, which is where container technology started. The Union File System (UnionFS) has been built in the Linux Kernel - this is part of the Linux Operating System. UnionFS has the functionality of merging file systems together whilst still keeping these files separate. It does this through creating read-only layers.
Using UnionFS, users can create multiple images that share the same data, without the need to keep copying it over to separate images. This can all be shared across multiple containers. This can be very beneficial for efficiency.
Containers can use a process called copy-on-write for making changes. This process only copies data when something needs to be modified. In this process, a new writable layer is created for the container. This technology both saves disk space, and makes start times far more efficient (as identical copies of the same thing aren’t loading).
Container images are fundamental to containerization. They are the building blocks, to the point that there would be no containers without them. Understanding what container images are, how they work, and how they differ from containers is intrinsic to getting to grips with containerization overall. Additionally, knowing how images work in relation to Docker is also key, as Docker powers much of the container ecosystem.
Stay up to date! Connect with us on LinkedIn and X/Twitter to get exclusive insights and be the first to discover our latest blog posts.
Experience Divio's Open Cloud with our 30-day Free Trial!
Easily deploy your web applications and explore customized solutions.
Sign up now!