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 |
Software | Docker |
Other | Privileged access to your Linux system as root or via the sudo command. |
Conventions |
# – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command$ – 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
Ubuntu
In Ubuntu Bionic Beaver 18.04, having Docker installed is straightforward.
# apt install docker.io
Debian
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.
CentOS
In CentOS 1804, it’s one yum
command.
# yum install docker
Fedora
In Fedora 28 it’s also ready to be installed with one dnf
command.
# 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 hello-world
container.
$ 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.
The -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 -v
mapping.
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.
Conclusion
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.