Understanding Docker Images.

Subscribe to my newsletter and never miss my upcoming articles

In my last post of this series, we discussed what happens behind the scenes in containers, created them manually (without using Docker), and realized how miserably long it would take for us to create just a bare-minimum of what could be called a containerized environment, let alone other issues like network layer and managing it, etc. My hope is that exercise made you a bit more considerate towards Docker 🙂

Now that we can imagine how immensely helpful Docker can be, going forward in this series, I'll explore some very helpful tools that can work with/comes with Docker, and can make our lives as developers, further easier. One such great resource are the tens of thousands of Docker images provided to us on Docker hub . Let's see how we can utilize them!

Wha...aa... Docker images, did you say?


I think Buzz is funny, who is with me? 😃 Anyway, let's not get distracted here.

There are many definitions for Docker images on the internet, but one way of understanding I find particularly helpful is that these are pre-built containers, that are readily available on Docker hub to just grab and run. More technically, they are an immutable file system, created using the build command and every time we run one of these images, it creates an instance of that type of container, for example say, Ubuntu, Alpine, Node to name a few.

Let's try to create an ubuntu:bionic container image and see this in action.

$ docker run --interactive --tty ubuntu:bionic # or: docker run -it ubuntu:bionic

It's that simple! 💃🏽

The above command would run aka execute an existing container image (as opposed to building anew) and drop you in a shell inside of the container as the root user of that container. When you're done, just run exit or hit CTRL+D.

If you tried the same command without the --interactive --tty or -it for short, you'd not see much happening. This is because -it tells Docker that you'd like to be dropped into the container interactively so you can run commands and inspect it. When you leave this flag out, the container starts and then because it has nothing to do, it just exists.

If there is exactly one command you'd like to execute, you could also do:

$ docker run ubuntu:bionic <CMD> # replace <CMD> with desired command like ls, cat, etc.

Some useful commands to note:

Let's look through a few more foundational docker commands:

1.detach : Let's you run a container in the background. You can use it as:

$ docker run --detach -it ubuntu:bionic # or: docker run -dit ubuntu:bionic

If you wanted to get a hold of it back on the foreground, we use another command called,

2.ps : This will print out all the running containers that Docker is managing for you, along with their PIDs and names.

$ docker ps

From the list we get back, go ahead and copy the one which you want on the foreground and run the next command,

3.attach : This allows you to attach a shell to a running container and lets you play around with it.

$ docker attach <PID or container_name>

After you are done with the container and want to get rid of it, we can use this next command,

4.kill : You guessed it, it kill s (😈 ) the container.

$ docker kill <IDs or names of containers>
$ docker kill $(docker ps -q) # to kill all containers running at any given time.

And now, I'd like to point to two other flags, I think would help simplify things and keep the number of containers on your system under check.

Honorary mentions 👏🏼

1.--name : You can name your own container! Isn't that exciting now. 🤓

$ docker run -dit --name worlds-best-container ubuntu:bionic

Congrats! Now you can refer to your container as the worlds-best-container , undisputedly.

2.Now say, we went ahead and ran these commands,

$ docker kill worlds-best-container 
$ docker ps --all

What!? worlds-best-container still exists even after you ran the kill command on it. It's invincible! 🤯

Nah, this is just because Docker keeps some metadata from the containers you have run until you tell it to stop doing that. So go ahead and use --rm like so to achieve just that.

$ docker rm worlds-best-container # or for any future containers run to automatically clean up: docker run --rm -dit --name <NAME> ubuntu:bionic


Yay! With all that you now know how to get an image from Docker hub and the basics of managing it from your terminal. In the next article of this series, I'll be going over some more cool features of the Docker CLI.

Till then, happy coding!

Ayush's photo

Nice blog

Tanvi Priyadarshini's photo

Thanks! It's a full series I am writing, hopefully it helps :)

Bolaji Ayodeji's photo

Very well written, thanks for writing this!

Tanvi Priyadarshini's photo

So happy you enjoyed it!

Wachukwu Emmanuel's photo

This is a very cool piece Tanvi Priyadarshini.

I started docker early today and thus far, I have been really enjoying it.

Plus, I love the fact that I can name my containers from your article. It's really cool.

Just to add a little, when the run command is used, it's creates a container from th on an image, the docker daemon performs twothings which are to create a container using the sspecified image and start the container as well.

I'm anticipating more of this series.

Tanvi Priyadarshini's photo

Thanks Wachukwu Emmanuel!

I am so glad you enjoyed the article, and yes when managing multiple containers I find the --name so helpful!

I am going to write a few more articles under this series, so come back for them and let me know how they helped you :)

IROEGBU!'s photo

This is really easy to get anybody started. Very well written and straightforward. With a subtle explanation of the difference between images and containers (confuses many people).