Docker: Introduction
Docker is an open platform management tool for Linux Containers. It provides a means for developers and system administrators to build and package applications into lightweight containers. Docker consists of the following components:
- Docker Engine – A portable, lightweight runtime and packaging tool
- Docker Hub – A cloud service for sharing applications and automating workflows
Docker is used to create image-based application containers. Image-based containers package an application with the individual runtime stack into a single container. This makes the container independent from the host operating system and kernel version. As a result, you can run the same application, unchanged, on laptops, data center virtual machines, and any cloud. You can transfer this container to another machine that runs Docker and runs the application without any compatibility issues.
The following lists additional advantages of running applications within Docker containers:
- Docker images contain only the content needed to run an application so they are smaller than virtual machines, which require the entire operating system.
- A Docker container runs faster than an application that includes the overhead of an entire virtual machine.
- A Docker container includes its own network interfaces, file system, and memory, which allows the application running in the container to be isolated and secured from other processes on the host computer.
Docker Images
Docker containers are built from Docker images. You create Docker containers to run your applications from these Docker images. The following example creates a Docker container named “test” from a Docker image named centos:7” and runs /bin/bash.
# docker create --name test centos:7 /bin/bash Unable to find image 'centos:7' locally Trying to pull repository docker.io/library/centos ... 7: Pulling from docker.io/library/centos 469cfcc7a4b3: Pull complete Digest: sha256:989b936d56b1ace20ddf855a301741e52abca38286382cba7f44443210e96d16 Status: Downloaded newer image for docker.io/centos:7 a79ce1655f2ca17c7ac8cc15f307ba0bb438fbebd4595568df3433dd5ff79b73
Images are read-only templates that can contain an entire operating system with services and additional applications installed. Docker provides the capabilities to build images or update existing images. You can create Docker images from the command line or you can store the instructions to build an image in a Dockerfile. Docker reads this Dockerfile and executes the instructions when you initiate the build of a Docker image.
Each image starts from a base image (for example, centos). Each Docker image consists of a series of layers that are built from these base images. Each instruction in the Dockerfile creates a new layer in the image. Each time you make a change to a Docker image, only that layer is updated or added. Docker uses unionfs to combine these layers into a single image. The unionfs file system service allows files and directories of separate file systems to be overlaid into a single file system.
After you create a Docker image, you can share the images by storing them in Docker registries. These registries can be private or public. Docker Hub is the public Docker registry that acts as a Software-as-a-Service platform for sharing and managing Docker containers.
The Docker Hub Registry
The Docker Hub Registry hosts applications as Docker images and provides services that allow you to create and manage a Docker environment. The Docker Hub Registry is owned and maintained by Docker, Inc. and is located at https://registry.hub.docker.com/.
Docker Hub provides a number of repositories and each repository can contain a number of images. In addition to hosting Docker images, Docker Hub provides services such as user authentication, automated image builds and work-flow tools, and integration with GitHub and BitBucket. To use these Docker services, you need to create a Docker Hub account. You can create an account at https://hub.docker.com/account/signup/. You can also create an account from the command line by using the following command:
# docker login
You can search for Docker images and pull (download) images from the Docker Hub without having an account. To push (upload) images, leave comments on an image or repository, and use all available Docker Hub services, you need a Docker Hub account.
Installing and Starting Docker
Installing and starting the docker service is an easy task. You can use the following command to install the docker package:
# yum install docker
Use the systemctl command to enable and start the docker service.
# systemctl enable docker # systemctl start docker
By default, Docker uses devicemapper as the storage driver. With RedHat Linux 7, you can configure the Docker Engine to use Btrfs. This allows you to take advantage of the snapshot features of Btrfs. The following command displays all the files that are installed from the docker package:
# rpm -ql docker /etc/docker /etc/docker/certs.d /etc/docker/certs.d/redhat.com /etc/docker/certs.d/redhat.com/redhat-ca.crt /etc/docker/certs.d/redhat.io /etc/docker/certs.d/redhat.io/redhat-ca.crt ...
You can see that, in addition to the docker binaries and configuration files, documentation and man pages are installed for all of the docker commands. The /var/lib/docker directory is empty until the docker service is started. The following series of commands displays the contents of the directory before and after starting docker.
# ls /var/lib/docker # systemctl enable docker # systemctl start docker # ls /var/lib/docker containers graph linkgraph.db tmp volumes devicemapper init repositories-devicemapper trust
The docker Utility
The docker command-line interface has over 30 commands. Refer to the docker man page for a list of the commands. The docker info command displays systemwide information about the Docker installation. See the docker-info man page for more information. Note that the default storage driver is devicemapper and that data and metadata are stored in loop devices: /dev/loop0 and /dev/loop1.
# docker info Containers: 1 Running: 0 Paused: 0 Stopped: 1 Images: 1 Server Version: 1.13.1 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: false Native Overlay Diff: true Logging Driver: journald ...
Users other than root can run docker commands if you add them to the docker group and reconfigure the docker service.
Searching the Docker Hub Registry for Images
Use the docker search command to search the Docker Hub for images. Shown below is the output of the “docker search” command:
# docker search centos INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED docker.io docker.io/centos The official build of CentOS. 4207 [OK] docker.io docker.io/ansible/centos7-ansible Ansible on Centos7 108 [OK] docker.io docker.io/jdeathe/centos-ssh CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8... 94 [OK] docker.io docker.io/consol/centos-xfce-vnc Centos container with "headless" VNC sessi... 52 [OK] docker.io docker.io/imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 40 [OK] ...
This command searches the Docker Hub for “centos” images. The output includes the name of the repository/image, a description, the number of stars awarded, whether the image is official, and whether it is automated. The name column is in the following form and can include the containing repository to provide a unique identification:
[repository_name]/[image_name]
Stars measure the popularity of images. Anyone with a Docker Hub account can “star” an image if they like it. The following example searches for “centos” images with at least 3 stars:
# docker search -s 3 centos Flag --stars has been deprecated, use --filter=stars=3 instead INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED docker.io docker.io/centos The official build of CentOS. 4207 [OK] docker.io docker.io/ansible/centos7-ansible Ansible on Centos7 108 [OK] docker.io docker.io/jdeathe/centos-ssh CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8... 94 [OK] ...
An “official” repository is certified by a vendor or contributor to Docker. An “automated” image is built by the Docker Hub’s automated build process.
Downloading Images from Docker Hub
Use the “docker pull” command to download an image or a repository from the Docker Hub Registry to your local system. Following example pulls down the centos:latest image.
# docker pull centos Using default tag: latest Trying to pull repository docker.io/library/centos ... latest: Pulling from docker.io/library/centos Digest: sha256:989b936d56b1ace20ddf855a301741e52abca38286382cba7f44443210e96d16 Status: Downloaded newer image for docker.io/centos:latest
Use the “docker images” command to list images stored in the local Docker repository.
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos 7 e934aafc2206 2 weeks ago 199 MB docker.io/centos latest e934aafc2206 2 weeks ago 199 MB
Each image in a repository is distinguished by TAG and IMAGE ID.
The following shows the location of the docker configuration files.
# cd /var/lib/docker/ # ll total 4 drwx------. 3 root root 77 Apr 21 07:57 containers drwx------. 3 root root 21 Apr 21 07:56 image drwxr-x---. 3 root root 18 Apr 21 07:56 network drwx------. 6 root root 4096 Apr 21 07:57 overlay2 drwx------. 4 root root 30 Apr 21 07:56 plugins drwx------. 2 root root 6 Apr 21 07:56 swarm drwx------. 2 root root 6 Apr 21 07:57 tmp drwx------. 2 root root 6 Apr 21 07:56 trust drwx------. 2 root root 24 Apr 21 07:56 volumes
Running an Application Inside a Container
Use the docker run command to run an application inside a container. This command starts a process with its own file system, its own networking, and its own isolated process tree. The following syntax does not include all of the available options for the command:
# docker run [OPTION...] IMAGE [COMMMAND] {ARG...]
The IMAGE that starts the process can define defaults related to the process to run in the container, the networking, and more, but docker run options override settings in the IMAGE. If the IMAGE is not available locally, docker run pulls the image in the same way as the docker pull command before it starts the container in the IMAGE.
Shown below are two examples of using docker run. The first example uses the “centos” image, which already exists on the local machine. Docker uses the image to create a new CentOS environment and then runs the echo command to display “Hello”.
# docker run centos /bin/echo "Hello" Hello
The second example uses the fedora image, which is not present on the local system. Docker pulls the image from Docker Hub and then uses the image to create a new Fedora environment and runs the echo command.
# docker run fedora /bin/echo "Hello" Unable to find image 'fedora:latest' locally Trying to pull repository docker.io/library/fedora ... latest: Pulling from docker.io/library/fedora 2176639d844b: Pull complete Digest: sha256:ec588fc80b05e19d3006bf2e8aa325f0a2e2ff1f609b7afb39176ca8e3e13467 Status: Downloaded newer image for docker.io/fedora:latest Hello
In both examples, the Docker containers stop after “Hello” is displayed to the screen. Use the docker ps command to list containers and no containers are displayed:
# docker ps
Thats because “docker ps” only shows currently running containers. To show all the containers including the stopped ones, use the “docker ps -a” command.
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b772ea59c92 fedora "/bin/echo Hello" 25 seconds ago Exited (0) 23 seconds ago vigilant_haibt 263e715ae13c centos "/bin/echo Hello" About a minute ago Exited (0) About a minute ago condescending_aryabhata a79ce1655f2c centos:7 "/bin/bash" 4 hours ago Created test
The docker images command shows that the “latest” image from the “fedora” repository was downloaded from Docker Hub when using the docker run command:
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos 7 e934aafc2206 2 weeks ago 199 MB docker.io/centos latest e934aafc2206 2 weeks ago 199 MB docker.io/fedora latest 9110ae7f579f 6 weeks ago 235 MB
Running an Interactive Docker Container
Use the –t and –i options with the docker run command to run an interactive container. These options are described:
- -t: Allocate a pseudo-tty and attach to STDIN (standard input) of a container
- -i: Keep STDIN of a container open
Shown below are two examples of using docker run commands with the –t and –i options. In both examples, CentOS Linux 7.4 is running on the local system:
# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core)
The first example uses the “centos:7” image. Docker uses the image to create a new CentOS environment and then runs the bash shell command. The OS version of this image is CentOS 7.
# docker run -t -i centos:7 /bin/bash [root@b3e1316c4653 /]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core)
The second example uses the ubuntu image. Because no specific image was specified, Docker uses the “latest” Ubuntu image to create a new Ubuntu environment and then runs the bash shell command. The OS version of this image is Ubuntu 16.04.4. Also as the ubuntu image is not locally available, docker will first download it from repository and then run it.
# docker run -t -i ubuntu /bin/bash Unable to find image 'ubuntu:latest' locally Trying to pull repository docker.io/library/ubuntu ... latest: Pulling from docker.io/library/ubuntu d3938036b19c: Pull complete a9b30c108bda: Pull complete 67de21feec18: Pull complete 817da545be2b: Pull complete d967c497ce23: Pull complete Digest: sha256:9ee3b83bcaa383e5e3b657f042f4034c92cdd50c03f73166c145c9ceaea9ba7c Status: Downloaded newer image for docker.io/ubuntu:latest
root@9ee24718262c:/# cat /etc/os-release NAME="Ubuntu" VERSION="16.04.4 LTS (Xenial Xerus)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 16.04.4 LTS" VERSION_ID="16.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" VERSION_CODENAME=xenial UBUNTU_CODENAME=xenial
You can use the exit command or press CTRL + D to exit an interactive container.
Listing Containers and Viewing Container Logs
Use the docker ps command to list information about Docker containers. By default, only running containers are listed. Include the –a option with the docker ps command to show all containers. Output includes a unique container ID and unique container name which are automatically generated when the container is created. Output of the docker ps command also includes the image that was used to create the container, the command that is running in the container, and status information. Status information includes when the container was created, and how long the container has been running.
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9ee24718262c ubuntu "/bin/bash" 3 minutes ago Exited (127) 2 seconds ago modest_turing b3e1316c4653 centos:7 "/bin/bash" 6 minutes ago Exited (0) 4 minutes ago gracious_pare 7b772ea59c92 fedora "/bin/echo Hello" 18 minutes ago Exited (0) 18 minutes ago vigilant_haibt 263e715ae13c centos "/bin/echo Hello" 19 minutes ago Exited (0) 19 minutes ago condescending_aryabhata a79ce1655f2c centos:7 "/bin/bash" 4 hours ago Created test
The docker logs command looks inside the container and returns its standard output. You can use either the container ID or the container name as an argument to the command.
# docker logs b3e1316c4653 [root@b3e1316c4653 /]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) [root@b3e1316c4653 /]# exit exit
In the example above, the docker logs command shows that the “cat /etc/redhat-release” command was executed in the container. The docker ps and docker logs commands need to be executed from outside the container, that is from another terminal window.
Display All Information for a Container or an Image
Use the docker inspect command to view all the information available for a container or an image. The following example shows some of the information that is displayed. Use the –f {{.section.subsection}} option to display a specific piece of information. The following example displays only network settings:
# docker inspect -f {{.NetworkSettings}} modest_turing {{ 98e04ea6d68753022ae2212b06b1514323927a1ed117448bc70ea3fa9a2f4a06 false 0 map[] /var/run/docker/netns/98e04ea6d687 [] []} { 0 0 } map[bridge:0xc4200c0300]}
The following example displays the IP address:
# docker inspect -f {{.NetworkSettings.IPAddress}} modest_turing 172.17.0.10
The following example displays the process ID:
# docker inspect -f {{.State.Pid}} modest_turing 7181
The following example displays the command running in the container:
# docker inspect -f {{.Config.Cmd}} modest_turing [/bin/bash]
If you want to view all the options/properties of the container, do not use any option with “docker inspect”:
# docker inspect modest_turing [ { "Id": "9ee24718262c9f7ed3320019163a8b1b2bb1bccc83eb362a5512a74eaa4ad57f", "Created": "2018-04-21T12:22:21.983441857Z", "Path": "/bin/bash", "Args": [], "State": { ....
This will be a pretty long output showing all the properties of the container.
Creating a New Container
The docker run command runs a process in a new container. You can also use the docker create command to create a container that you can start at a later time. The syntax and available options for docker create are similar to the docker run syntax.
The example below creates a new container named “geeklab” from the centos:7 image, and when started, runs the bash shell command. A container name is automatically generated if you omit the –name option.
# docker create -t -i --name geeklab centos:7 /bin/bash 667fd40faeb69113d035f08e5a910275a8463aa2a6a0796833f590e878732e17
The output of the command is a very long unique container ID. The container does not start immediately as shown by the docker ps command, which only shows running containers by default:
# docker ps
You need to run “docker ps -a” to show all containers. The example pipes the output to grep and searches part of the container ID:
# docker ps -a | grep 667fd 667fd40faeb6 centos:7 "/bin/bash" About a minute ago Created geeklab
Starting, Stopping, and Removing a Container
Use the “docker start” command to start an existing container. Use the –a and –i options to attach the current shell’s STDIN (standard input), STDOUT (standard output), and STDERR (standard error) to the container and also cause all signals to be forwarded to the container.
# docker start -a -i geeklab [root@667fd40faeb6 /]#
From inside a container, use the exit command or CTRL-d to stop the container. From outside the container, that is from another terminal window, use docker stop command to stop a container.
# docker stop geeklab
Use the “docker rm” command to remove a container. You can remove multiple containers in a single command. Use the –f option to remove a running container.
# docker rm geeklab geeklab
All three of these docker commands accept either the container ID or the container name as an argument.
The docker rm command removes a container. Use the docker rmi command to remove an image:
# docker rmi [IMAGE]
Running Additional Commands in a Running Container
Use the docker exec command to run a command in a running container. Similar to the docker run command, include the –t and –i options to run an interactive command. Provide either the container ID or the container name as an argument.
In the following example, the docker exec command starts a new interactive bash shell in the “guest” container:
# docker exec -t -i geeklab /bin/bash [root@68b5b713c37b /]#
The following example uses the docker exec command to start the sshd service on the “geeklab” container. The “geeklab” container is running CentOS 6.4. In this example, the -t and -i options are not needed.
# docker exec guest service sshd start Generating SSH2 RSA host key: [ OK ] Generating SSH1 RSA host key: [ OK ] Generating SSH2 DSA host key: [ OK ] Starting sshd: [ OK ]
The sshd service is started on the container and control returns to the initiating host system.