Docker for absolute beginners: the difference between an image and a container

Learn the difference between Docker images and containerscontainers and images are different + practical code examples

Docker for absolute beginners: the difference between an image and a container
Since this is an article about Docker we MUST have a container-related cover, right? (image by Borderpolar Photographer on Unsplash)

Learn the difference between Docker images and containers + practical code examples

Containers, images, environments, building, running, virtual machines.. when you’re new to Docker all of these abstract terms can be a bit confusing. In this article we’ll go through all of them and get an understanding of each term. We’ll focus on explaining the difference between images and containers and how they work together, but along the way we’ll explore other Docker-related things. At the end of this article you’ll:

  • understand how to build an image
  • understand how to spin up an image
  • understand the difference between an image and a container
  • understand how to user Docker better in your day-to-day work

Let’s code!


Docker in a nutshell

Docker is the answer to ‘but it worked on my machine!’ Imagine that you’ve written a small program on your laptop: let’s say that it’s a simple Python API. Now you want to deploy this program on a laptop of a coworker or on a server. You copy the code, spin up the API and it crashes. Why?

There reasons for this can be many: maybe Python isn’t installed. Maybe the other machine has an OS that’s incompatible with your code. In other words: your program is built in one environment and doesn’t work in another.

Docker’s solution to this problem is very simple and very clever at the same time: instead of just deploying the code, we’ll deploy our environment as well. Docker creates a box, installs an OS in the box and copies over your source code. Then we give others the box. This is brilliant because once your code runs in this environment (box) that means that it runs anywhere.

In this article we’ll focus on how we build these boxes and how to share them. In other words: how we build images, spin them up into containers and deploy them on a server for example!

Containerized! (image by Teng Yuhong on Unsplash)

1. Creating an image

In the previous part we saw that with Docker we package our code with our environment so that we can run that. What we called a ‘box’ in the previous part is called an image. An image is the result of Docker’ build process. In the build process we use a Dockerfile. This is a file with instructions for building the container.

We’ll use lot of command line for the next part. If you are unfamiliar with using a terminal check out this article.

1.1 The dockerfile

Let’s check out a very simple dockerfile. Imagine we have a website that we want toFROM nginx:alpineCOPY c:/myproject/htmlfolder /usr/share/nginx/html

Two things happen here:
1. With the FROM keyword we tell Docker to pull a base image. In this case we use an image with nginx installed.

2. With COPY we instruct Docker to copy some code on our computer into the image. In this case we copy all code in our htmlfolder into the specified folder in the image. Nginx will host all code in this folder.


1.2 Building the image

Remember that so far we’ve only specified some instructions. Now we can actually build the image with docker build . -t my_image:v1.

The . in this command implies that docker can use a file called dockerfile in the current directory. You can also specify your Dockerfile if it is located elsewhere or named differently with
docker build -f c:/things/mydockerfile -t my_image:v1
As you can see we use the -f flag to pass the path to our dockerfile (called mydockerfile in this example.
With the -t flag we name and optionally tag our image in the name:tag format. Tagging our image makes it easier to work with later.

Our image is almost built (image by Randy Fath on Unsplash)

2. Spinning up a container

So far we’ve built an image with a Dockerfile. The resulting image, however, is not doing anything yet. We need to run it. You can spin up an image in two ways: with docker run and with a compose file. We’ll go through both.

Once an image is running it’s called a container.


2.1 Docker run an image

In this case we’ll run the image we’ve previously built. The easiest way is: docker run -p "81:80" my_image:v1. This runs our previously built image and maps port 81 on our laptop to port 80 in the container, which is where nginx is serving our website. This means that we can go to localhost:81 on our laptop to see the website. Easy!


2.2 Running images with docker-compose

If we have a lot of images we will spend a lot of time typing all of the docker run commands from the previous part. With docker-compose we can put this run configuration in a file so that we don’t have to type it every time. Install docker compose before continuing.

Another advantage of compose is that we can use it to link containers together. More on this in this article.

We’ll translate the command from the previous part to a run-configuration in docker compose. We’ll create a file called docker-compose.yml with the following content:version: "3.8"services:
 my_site:
   container_name: my_site
   hostname: my_site
   image: my_image:v1
   ports:
     - "81:80"

As you see the -p "81:80" translates to the last two lines. Also we’ve added some extra information about our host- and container-name. We specify that we want to run the image called my_image:v1 on the 7th line.

Notice that, like the Dockerfile, the docker-compose.yaml is nothing but a file that contains instructions. We have to run it in order to do something. We can just call docker-compose up if we’re in the same folder as the docker-compose.yml file or specify this file if it is located elsewhere or named something else with docker-compose -f c:/snacks/my_docker-compose.yml up.

Docker-compose makes it easy to run many (connected) images with one command and saves you a lot of typing.


3. The differences between images and containers

Now that we have some hands-on experience we can determine the differences between images and containers.

An image is like a class: a blueprint
A container is like an instance of a class

The most important difference is that an image is a logical object; it’s like a blue print while a container is a real-life object. An image is created only once ; containers, using the image, are created any number of times

A Dockerfile is more like a recipe: instructions for how to build something.
A compose file is more like a manual: instructions for how to use something.

You use a Dockerfile to build an image. This image is the combination of an OS and your source code.
Next you can spin up your image, resulting in container. You can spin up/run an image using docker run or a docker-compose.yml file in which you specify how it should run. A running image is called a container. Here is where you specify how the container fits in your deployment and here is also where you can link together containers e.g.

Ready to ship our code (image by Chris Pagan on Unsplash)

Conclusion

I hope that after reading this article you have a more clear understanding of both the vocabulary Docker uses, and the way Docker works. I hope this article was clear but if you have suggestions/clarifications please comment so I can make improvements. In the meantime, check out my other articles on all kinds of programming-related topics like these:

Happy coding!

— Mike

P.S: like what I’m doing? Follow me!

Join Medium with my referral link - Mike Huls
As a Medium member, a portion of your membership fee goes to writers you read, and you get full access to every story…