DevOps

Docker Tutorial: Play with Containers (Simple Examples)

Docker has had a huge impact on software development life cycle, making the deployment of software at scale easy and secure. This Docker tutorial will cover the basics of running, starting, stopping, and removing Docker containers.

Docker makes it so easy to work with different programming languages with different versions on different operating systems all this on the same host.

Deploying your software becomes a lot easier after Docker where you don’t have to worry about missing a system configuration or a prerequisite.

Docker VS Virtual machine

If you are using any kind of virtual machines to run your work inside it, why you would need Docker to run your work inside it instead? Well…

The main difference between them is that Docker is an isolated process that runs in your native OS while the virtual machine is a complete isolated OS that runs on top of your host OS which takes more time to load. So Docker has benefits over virtual machines such as:

  • Loading speed
  • Small hardware resources required, unlike virtual machines.
  • Running multiple Docker containers at the same time on the same OS.
  • You can modify your container and deploy it or give the Docker file definition to a friend to start working on the same environment.

Actually, Docker is not a replacement for virtual machines, it comes to solve specific problems.

Suppose that your application needs 3 or more services which run on different operating systems so instead of running 3 virtual machines on the same host, you can run 3 containers smoothly on the same host. Sounds great!!

Run your container

Before starting, ensure that Docker is installed correctly and is ready to accept your commands. Type the following command in a new Terminal window:

$ docker -v

The above command outputs the version of Docker installed on your PC:

 Docker version 17.12.0-ce-rc2, build f9cde63

Time to start running the container:

 $ docker container run alpine echo "Hello World"

When you run the above command for the first time, you should see an output in your Terminal window similar to this:

Unable to find image 'alpine:latest' locally
 
latest: Pulling from library/alpine
 
2fdfe1cd78c2: Pull complete
 
Digest: sha256:ccba511b...
 
Status: Downloaded newer image for alpine:latest
 
Hello World

That was easy, wasn’t it? Try running the same command again:

 $ docker container run alpine echo "Hello World"

The second, third, or nth time you run the above command, you should see only this output in your Terminal:

$ Hello World

Now that you have successfully run a container, it’s time to analyze what exactly happened. Look at the following command:

 $ docker container run alpine echo "Hello World"

This command contains multiple parts. First and foremost, you have the word docker. This is the name of the Docker command-line interface (CLI), used to interact with the Docker engine responsible for running containers.

Next, you have the word container, which indicates the context you are working with.

Next is the actual command you want to execute in the given context, which is run.

Now, you’d also need to tell Docker which container to run. In this case, this is the so-called alpine container.

Finally, you need to define what kind of a process or a task shall be executed inside the container when it is running. This is the last part of the command, echo “Hello World”.

Run a process inside a container

Now that you have understood the various parts of a command to run a container, try running another container with a different process running inside it:

 $ docker container run centos ping -c 5 127.0.0.1

This is the output:

Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
85432449fd0f: Pull complete
Digest: sha256:3b1a65e9a05...
Status: Downloaded newer image for centos:latest
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.019 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.029 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.030 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.029 ms
 
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4103ms

In the previous example, the container image you’ve used is centos and the process you’re executing inside the centos container is ping -c 5 127.0.0.1, which pings the loopback address five times until it stops.

  • The first line is as follows:
 Unable to find image 'centos:latest' locally

This tells you that Docker didn’t find an image named centos:latest in the local cache of the system. So, Docker knows that it has to pull the image from some registry where the container images are stored.

By default, your Docker environment is configured such that images are pulled from the Docker Hub at hub.docker.com. This is expressed by the second line, as follows:

 latest: Pulling from library/centos
  • The next three lines of output are as follows:
85432449fd0f: Pull completeDigest: sha256:3b1a65e9a05...Status: Downloaded newer image for centos:latest

This tells you that Docker has successfully pulled the image, centos:latest, from the Docker Hub.

All the subsequent lines of the output are generated by the process you ran inside the container, which is the ping tool in this case.

You may also have noticed the latest keyword occurring a few times. Each image has a version (also called a tag), and if you don’t specify a version explicitly, then Docker automatically assumes it as the latest version.

If you run the preceding container again on your system, the first five lines of the output will be missing since Docker will find the container image cached locally and so it won’t have to download it first. Try it out and verify.

Running a random quotes container

For the purpose of running a random quotes container, you’ll need an algorithm that produces random quotes. The API that produces those free random quotes can be found at https://talaikis.com/random_quotes_api/.

Now the goal is to have a process running inside a container that produces a new random quote every five seconds and outputs the quote to STDOUT:

while : 
do 
    wget -qO- https://talaikis.com/api/quotes/random 
    printf 'n' 
    sleep 5 
done

Stop the script by pressing Ctrl+C. Here’s the output:

{"quote":"Martha Stewart is extremely talented. He

Each response is a JSON-formatted string with the quote, its author, and its category.

Now, run this in an alpine container as a daemon in the background. For this, you’ll need to compact the preceding script into a one-liner and execute it using the /bin/sh -c "..."  syntax. The Docker expression will look as follows :

 $ docker container run -d --name quotes alpine \   /bin/sh -c "while :; do wget -qO- https://talaikis.com/api/quotes/random; printf '\n'; sleep 5; done"

In the above expression, you used two new command-line parameters, -d and –name. The -d tells Docker to run the process running in the container as a Linux daemon. The –name parameter can be used to give the container an explicit name.

If you don’t specify an explicit container name, Docker will automatically assign the container a random but unique name. This name will be composed of the name of a famous scientist and an adjective.

Such names could be boring_borg or angry_goldberg. Quite humorous, isn’t it?

One important takeaway is that the container name must be unique. Ensure that the quotes container is up and running:

 $ docker container ls -l

The important part of the preceding output is the STATUS column, which, in this case, is Up 16 seconds. This means that the container has been up and running for 16 seconds now.

Listing containers

As you continue to run containers over time, you’d eventually get a lot of them in your system. To find out what is currently running on your host, you can use the container ls command as follows:

 $ docker container ls

This will list all currently-running containers.

By default, Docker outputs seven columns with the following meanings:

ColumnDescription
Container IDThe unique ID of the container. It is a SHA-256.
ImageThe name of the container image from which this container is instantiated.
StatusThe status of the container (created, restarting, running, removing, paused, exited, or dead).
PortsThe list of container ports that have been mapped to the host.
NamesThe name assigned to this container (multiple names are possible).

If you want to list all the containers defined on your system, you can use the command-line parameter -a or –all as follows:

 $ docker container ls -a

This will list containers in any state, be it created, running, or exited.

Sometimes, you may want to just list the IDs of all the containers. For this, you have the -q parameter:

 $ docker container ls -q

You might wonder where this is useful. Here’s an example:

 $ docker container rm -f $(docker container ls -a -q)

The above command deletes all the containers currently defined on the system, including the stopped ones. The rm command stands for remove, and it will be explained further down in the tutorial.

In the previous section, you used the -l parameter in the list command. Try to use Docker help to find out what the -l parameter stands for. You can invoke help for the list command as follows:

 $ docker container ls -h

Stopping and starting containers

Sometimes, you may need to temporarily stop a running container. Try it out with the quotes container with this command:

 $ docker container run -d --name quotes alpine \   /bin/sh -c "while :; do wget -qO- https://talaikis.com/api/quotes/random; printf '\n'; sleep 5; done"

Now, you can stop this container with the following command:

 $ docker container stop quotes

When you try to stop the quotes container, you will probably note that it takes a while (about 10 seconds) until it’s executed. Why is this the case? Docker sends a Linux SIGTERM signal to the main process running inside the container.

If the process still doesn’t terminate itself, Docker waits for 10 seconds before sending SIGKILL, which kills the process forcefully and terminates the container.

In the above command, the name of the container is used to specify the container to be stopped. The container ID can also be used instead.

How do you get the container ID?

There are several ways of doing so. The manual approach is to list all the running containers and find the one that you’re looking for in the list. Just copy its ID from there.

A more automated way is to use shell scripting and environment variables. For example, if you want to get the ID of the quotes container, here’s an example::

 $ export CONTAINER_ID = $(docker container ls | grep quotes | awk '{print $1}')

Here we used AWK to get the first field which is the container ID. Now, instead of using the container name, you can use the $CONTAINER_ID variable in your expression:

 $ docker container stop $CONTAINER_ID

Once you stop the container, its status changes to Exited.

You can restart a stopped container with the docker container start command.

Removing containers

When you run the docker container ls -a command, you can see quite a few containers that are in the Exited status.

If you don’t need these containers anymore, it’s better to remove them from memory; otherwise, they unnecessarily occupy precious resources. The command to remove a container is as follows:

 $ docker container rm <container ID>

Alternately, you can also use this command:

 $ docker container rm <container name>

Sometimes, removing a running container will not work; if you want to force the removal, you can use the command-line parameter -f or –force.

Containerization has changed the way the industry used to operate by mitigating maintenance costs by over 50% and time-to-market by around 90%. Further, containers make applications more secure as opposed to running them outside containers.

If you found this tutorial helpful and want to learn more about Docker containers, you can read more from Learn Docker – Fundamentals of Docker 18.x, which explain all the critical concepts, related to containerization and orchestration.

Keep coming back. Thank you.

Published on Java Code Geeks with permission by Mokhtar Ebrahim, partner at our JCG program. See the original article here: Docker Tutorial: Play with Containers (Simple Examples)

Opinions expressed by Java Code Geeks contributors are their own.

Mokhtar Ebrahim

LikeGeeks: Learn more about Linux, Server Administration, Web Development, Python, iOS, and Tech Tips
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button