Docker’s popularity skyrocketed since it’s introduction in 2013. Companies and individuals now use or are planning to use it whether on premises or in the cloud. Docker’s flexibility appeals to developers, system administrators, and management.
This article shows how to get started with Docker, showing basic commands to get you into the container’s bandwagon.
In this tutorial you will learn:
- What is Docker and how it is used.
- How to install Docker on Linux.
- How to run Docker containers.
Software Requirements and Conventions Used
|Category||Requirements, Conventions or Software Version Used|
|System||Any Linux Distribution|
|Other||Privileged access to your Linux system as root or via the
# – requires given linux commands to be executed with root privileges either directly as a root user or by use of
$ – requires given linux commands to be executed as a regular non-privileged user
Basic Docker Concepts
Traditional virtualization platforms, like Virtualbox and VMWare, abstract an entire computer, aiming at isolating the host and guest operating systems, and requiring that an entire operating system is installed in the guest virtual machine (VM). Docker’s virtualization takes a different approach — it abstracts only the operating system, which means that host and guests share the same kernel.
The advantages are that guests (called containers) do not have to pack an entire operating system, what makes them lightweight – small in size and very fast to boot. Besides, by interfacing directly with the host operating system, Docker containers do not incur in performance penalties of traditional virtualization, which requires the translation of system calls between guest and host operating systems through drivers that abstract a virtual hardware.
The disadvantages are that it’s not possible to host a Windows guest on a Linux host, for example, and that all guests share resources (CPU, RAM, and disk) on the host, which means that a misbehaved container may bring the entire server down. It’s certain that Docker does not intend to replace traditional virtualization, which still has many valid scenarios. It just provides another way of obtaining application isolation while reducing libraries dependencies, without losing performance.
Docker allows you to launch containers, which are running instances of images. An image contains the disk with all libraries dependencies required to execute an application, while a container contains the context of execution. There can be multiple containers of the same image executing at the same time, each separated from the others.
There is a recommendation that a Docker container executes one application only, which frequently is misinterpreted to “running only one process”. There’s no problem to run more than one process in a container, as long as they belong to the same application. A complex application may, however, require the execution of multiple containers, like, for example, one for the webserver (Apache, Nginx), one for the application (php-fpm), and one for the database (MySQL, PostgreSQL, MongoDB). Those containers may execute in the same or in different hosts. Containers in the same host communicate through a virtual network managed by Docker.
Docker images are retrieved from a repository named registry and are cached locally. If a registry isn’t specified, docker will try to find the image at the default repository, called the Docker Hub. The Docker Hub contains an enormous quantity of images ready to be used provided by companies and individuals — and you can publish your images too. Besides, there’s also the Docker Store, where companies can professionally offer curated images of their software. It’s recommended you spend some time browsing and learning how those repositories work.
Enough said, let’s install Docker and learn some basic commands.
Installing Docker on Linux
In Ubuntu Bionic Beaver 18.04, having Docker installed is straightforward.
# apt install docker.io
If you are running Debian testing or unstable, the command above will also work. For Debian stable (Stretch), visit our Docker engine on Debian 9 Stretch Linux installation guide.
In CentOS 1804, it’s one
# yum install docker
In Fedora 28 it’s also ready to be installed with one
# dnf install docker
After Docker Installation
Once it’s installed, you can check Docker service is running.
# service docker status
If it’s not, then start it.
# service docker start
Once the service is running, you can check if there are any running containers.
# docker ps
If you don’t want to type
sudo to interact with docker service, just add your user to docker group. You need to login again to make the change take effect.
# usermod -a -G docker username
After login, check you are in docker group
$ groups roger adm cdrom sudo dip plugdev lpadmin sambashare docker
Now you don’t need
sudo to interact with the docker engine.
Running a Docker Container
Let’s execute a
$ docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world d1725b59e92d: Pull complete Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
The command is really simple, but many things happened. First, the docker engine realized the requested image wasn’t in the local cache ( Line 2 ). Then the image is pulled from the docker registry and stored locally ( Line 3 ). Finally, a container is created, executed ( Line 8 ) and terminated. If you try again, you’ll notice the execution is much faster since both, image and container, are cached. Now check the images stored locally.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 4ab4c602aa5e 2 weeks ago 1.84kB
Notice that the
hello-world image is minimal, with just 1.84 KB of size. This illustrates that much of the host operating system is used and that the image only contains the application dependencies.
You can remove this image.
$ docker images rm hello-world $ docker images
Now let’s do something more ambitious: pull and Apache webserver image and run a container.
$ docker pull httpd Using default tag: latest latest: Pulling from library/httpd f189db1b88b3: Pull complete ba2d31d4e2e7: Pull complete 23a65f5e3746: Pull complete 5e8eccbd4bc6: Pull complete 4c145eec18d8: Pull complete v1'1c74ffd6a8a2: Pull complete 1421f0320e1b: Pull complete Digest: sha256:8631904c6e92918b6c7dd82b72512714e7fbc3f1a1ace2de17cb2746c401b8fb Status: Downloaded newer image for httpd:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 4ab4c602aa5e 2 weeks ago 1.84kB httpd latest d595a4011ae3 6 weeks ago 178MB
Then you run a container from this image.
$ docker run -d -p 8000:80 httpd dd703b1590a91bdc10488b48798e42ddecd1c6519324a613f4b5563c21874a98 roger@slash:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dd703b1590a9 httpd "httpd-foreground" 10 seconds ago Up 3 seconds 0.0.0.0:8000->80/tcp cranky_torvalds
In it’s simplest form, the command would be
docker run httpd, but the container would be stopped right after Apache was running, and no port would be exposed. The
-d (detach) option is needed so that the container stays running in background.
-p 8000:80 option is mapping port 80 of the container to port 8000 in the host, making the webserver available in the network. By default, container ports are not exposed to the host. Now, you can point a web browser to
http://localhost:8000 and see the Apache test page.
Ok, but how to change the webpage? We need to link a folder from the host into the container
/usr/local/apache2/htdocs/ directory (we’ll see later that the Apache image is built from a Debian Jessy, regardless of the linux flavor of your host). Stop the container and run it again.
$ docker ps $ docker stop cranky_torvalds $ echo "<html><body>My Webpage</body></html>">index.html $ docker run -d -p 8000:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd
We created an
index.html file in the current directory in the host and mapped this directory inside the
htdocs directory of the container with the
-v switch. Now refresh the web browser.
Now the topping: experiment editing the
index.html file in the host and refresh the web browser, without changing the state of the container. Yes, whenever a file is edited, or a new file is added to the current directory, it is made available inside the container because of the
Create another file and access it in the browser.
$ echo "Second page" >index2.html
When you are done, stop the container execution.
$ docker stop angry_poincare
Notice that now you have a webserver ready to be executed whenever you need it, and you didn’t touch any configuration file in your operating system. It’s all encapsulated in the Apache image that is cached by docker. Moreover, you can download the image and start a container on any other computer.
This article introduced the main Docker concepts and some basic commands. I hope you understand the benefits and see that, once the concepts are understood, it’s not complicated to use Docker. Future articles will present other features and use cases.