Using Docker – Installation

If you follow me on Twitter (@john_canessa) you have noticed that in the past couple months or so I have been posting tweets regarding articles in Medium. The site is geared to creating posts which you could do using your own web site (e.g., The beauty is that many talented individuals in different fields are posting there. The site organizes them by categories and presents the articles indicating the estimated reading time. One of these days I will probably start posting there.

Of dozens of articles that I have read on Medium, I have noticed that explicitly or implicitly the way they are written follows two well known patterns which I have used for decades. The first one is to read and then experiment. One can read about a subject and get a general idea on it. You need to experiment, make mistakes and use or create examples that interest you. The second pattern is to explain the subject at a 6 year old level. Not all the articles get to this point, but in general the authors attempt to explain as simply as possible the steps to achieve a goal. At work I architect, design and implement code attempting to explain as well as I can. Keep in mind that if you cannot explain something, you do not understand it yourself.

I am very interested, among other things, in Docker. This post deals with chapter two of the book “Using Docker” by Adrian Mouat, ISBN: 978-1-491-91576-9. I have read a few books regarding Docker and have found this as the best so far. I typically get my books from Amazon. I strongly recommend getting a copy, reading a chapter at a time and then spending time experimenting as long as you think is enough with the examples. In future posts, I will be touching on most (if not all the chapters) in the “Using Docker” book.

If you have been reading my posts and tweets, I am very interested in what is generally known as Artificial Intelligence (AI). One of the languages mostly used is Python. There is a Jupyter Notebook that in one place (the notebook) an author / developer can put the code, the engine that parses the code and the actual data. That is a great thing to use. If you have an issue, you can send / post the notebook and a reviewer is able to follow the code and reproduce the bugs / results. This is great for peer review.

Of course there are some limitations. I am not sure how many other languages are supported by Jupyter. One must also take into considerations the different versions of hardware, operating systems, and tools. Docker deals with containers. In a nutshell a container represents a virtual computer that has been used to test / run the software being developed. The great thing of Docker is that the virtual computer with the actual code and data can be shared and runs on most (never say any) machines with some limitations. For example, a Docker container created under Windows runs on Windows machines. The same holds true for Linux. Given that Docker was developed using Linux features, we will use Linux in this set of posts.

If you are interested and getting a better overview regarding containers and in specific Docker, the first chapter in “Using Dockers” might be all what you need. There is a lot of information on the web; some of which may be overkill and / or not be up to date.

Without further ado, let’s dive into the subject of this post.

The first thing to do is to install Docker on your machine. I have installed it on Linux and Windows. It makes sense to start with Linux, and if needed move on to Windows.

You need to have a relatively current version of Linux and download and install a current version of Docker. Both Docker and Linux are constantly and rapidly evolving so it is not a good idea to use stale versions.

Let’s determine the version of Linux running on our machine. The following command lists a set of one of more files which contain the information we are seeking. At this time we do not know the exact count or names.

$ ls -l /etc/*-release      
-rw-r--r--. 1 root root  38 Aug 30 10:53 /etc/centos-release
-rw-r--r--. 1 root root 393 Aug 30 10:53 /etc/os-release
lrwxrwxrwx. 1 root root  14 Nov  5 20:09 /etc/redhat-release -> centos-release
lrwxrwxrwx. 1 root root  14 Nov  5 20:09 /etc/system-release -> centos-release

By the names of the files it seems that we are running a Linux CentOS distribution. We can now take a look at the contents of the different files and get the actual name of the distribution by using:

$ tail -vn +1 /etc/*-release
==> /etc/centos-release <== CentOS Linux release 7.4.1708 (Core) ==> /etc/os-release <== NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="" BUG_REPORT_URL="" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7" ==> /etc/redhat-release <== CentOS Linux release 7.4.1708 (Core) ==> /etc/system-release <==
CentOS Linux release 7.4.1708 (Core)

The /etc/centos-release file indicates we are using CentOS Linux release 7.4.1708 (Core). Any version greater or equal to CentOS 7.0 is good.

We can now check that the Linux kernel version and CPU architecture is what Docker requires. We can do this as follows:

$ uname -a
Linux localhost.localdomain 3.10.0-693.11.6.el7.x86_64 #1 SMP Thu Jan 4 01:06:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

This command lists all the information but we need to know where it is located in the string. To get the Linux kernel version:

$ uname -r

We are running a version that is higher than 3.10. All is well so far.

We should verify that our CPU is 64-bit and not 32-bit. The following command will display the CPU architecture:

$ uname -m

This is a 64-bit processor so we are good.

The next step is to download the installation script for Docker. We can download it using one of the two commands:

$ curl > /tmp/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  100 11249  100 11249    0     0   2133      0  0:00:05  0:00:05 --:--:-- 63553


$ curl -fsSL -o /tmp/

Once the script has been downloaded you might want to take a look at what it does. Opening the file with a text editor to review it makes sense:

$ gvim /tmp/

I like to use gvim, but any other editor (not word processor) would be fine.

To install Docker I used the following:

$ chmod +x /tmp/
$ /tmp/

After Docker was installed, I removed the installation script. You may choose to keep it for later reference.

$ rm /tmp/

If you would like to use Docker as a non-root user, you should now consider adding your user to the “docker” group with something like:

$ sudo usermod -aG docker johncanessa

The “Using Docker” book suggests running in permissive (0) mode. My installation started as follows:

$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

You can change the current mode (enforcing == 1 OR permissive = 0)

$ sudo setenforce 0

I decided to leave it in enforcing and decide to switch to permissive if and when the need arises.

To start the Docker service you may enter the following command:

$ sudo service docker restart

At this point if all went well, Docker should be up and running. To verify this you could use the following:

$ docker version
 Version:	18.02.0-ce
 API version:	1.36
 Go version:	go1.9.3
 Git commit:	fc4de44
 Built:	Wed Feb  7 21:14:12 2018
 OS/Arch:	linux/amd64
 Experimental:	false
 Orchestrator:	swarm

  Version:	18.02.0-ce
  API version:	1.36 (minimum version 1.12)
  Go version:	go1.9.3
  Git commit:	fc4de44
  Built:	Wed Feb  7 21:17:42 2018
  OS/Arch:	linux/amd64
  Experimental:	false

If the Docker server portion does not display, there is an issue that needs to be resolved. In my case all went well. I recall the first time I installed Docker on Windows; the server did not come up. After enabling some software and adding some RAM, all came up.

A command you might want to keep handy is:

$ docker help

Usage:	docker COMMAND

A self-sufficient runtime for containers

      --config string      Location of client config files (default "/home/johncanessa/.docker")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/home/johncanessa/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/home/johncanessa/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/home/johncanessa/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  config      Manage Docker configs
  container   Manage containers
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  swarm       Manage Swarm
  system      Manage Docker
  volume      Manage volumes

  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

I tend to forget things so taking note on how to get some help is always useful.

You should first read the second chapter in “Using Docker”; follow the steps and then try different things to learn and understand how to install Docker.

In a following post I will cover the next chapter in the book.



Leave a Reply

Your email address will not be published. Required fields are marked *

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