Introduction

What is Docker?

Docker is an open source container based technology.

What is a Container?

To more easily explain what containers are, let’s compare them to Virtual Machines:

  • A Virtual Machine includes the application, the necessary binaries and libraries and a guest operating system. This means that it tries to do everything a computer has to do, which is quite resource intensive.
  • A Container is different from a Virtual Machine. It’s like a box that includes the application and all the dependencies associate with it, but shares the host operating system’s kernel. You can think of it as a lightweight server that contains just enough for it to be whatever it needs to be.

“The Kernel” of an operating system is a collection of software that is the minimum needed to run various hardware. It has complete access and control over everything in and pertaining to the system and is the first thing loaded of your system. It also contains drivers, the bits of code that communicate with and control hardware. [ref: /r/explainlikeimfive ]

Why use Docker?

In short, with Docker, only our application and it’s dependencies are contained, which makes it extremely fast and extremely portable, and we don’t have to worry about the OS.

Step 1 — Installing Docker on Ubuntu

Update your package index:

$ sudo apt update

Install the necessary packages so `apt` can use packages over HTTPS:

$ sudo apt install apt-transport-https ca-certificates curl software-properties-common

Add the official Docker repository’s GPG key to your system:

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Add the Docker APT repository to your system’s APT sources:

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"

Update your list of packages again, since we just added the Docker repository:

$ sudo apt update

Now we can install the latest version of Docker CE (Community Edition):

$ sudo apt install docker-ce

After the installation is complete, the Docker service will start automatically. You can check it’s status by running the following command:

$ sudo systemctl status docker

The output will look something like this:

sudo systemctl status docker
● docker.service -- Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2018-11-25 09:25:30 PST; 44min ago
     Docs: https://docs.docker.com
 Main PID: 442 (dockerd)
    Tasks: 19
   CGroup: /system.slice/docker.service
           ├─442 /usr/bin/dockerd -H fd://
           └─470 docker-containerd --config /var/run/docker/containerd/containerd.toml
lines 1-19/19 (END)

If you find that the terminal is locked in the `systemctl` command’s output as it displays the status information of the requested service ( docker in this case ), then just press `q` to quit.

You’ve now installed Docker. This gives you the Docker service and also the Docker Client, or `docker` command line utility. We can start using the `docker` command to check our Docker version. Here’s my version at the time of writing:

docker -v
Docker version 18.09.0, build 4d60db4

Step 2 — Allowing Non-sudo Access (Optional)

This step is optional.

If you’d like to execute the `docker` command without being `root` or always prefixing it with `sudo`, then you’ll have to add your username to the `docker group`:

$ sudo usermod -aG docker your_username

To apply the new membership, you’ll have to log out of your current user by typing `exit` or `CTRL+D` and logging back in. You can then test if the changes applied by checking if the user is now part of the docker group:

$ id -nG
id -nG
vlad sudo docker

NOTE: In the rest of this tutorial we’ll assume that you’re running the `docker` command as a user that’s not part of the `docker` group, so we will prefix `sudo` for every command, but you don’t have to if you’ve added your current user to the `docker` group.

The reason we continue this way is because some readers may just scan this tutorial for commands.

Step 3 — Docker Command Basics

The `docker` command has the following structure:

$ sudo docker [option] [command] [arguments]

To view all the available commands, just run:

$ sudo docker

The list of commands and subcommands in Docker 18 includes:

  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

To get help on a specific [subcommand] then just run:

$ sudo docker docker-subcommand --help

For system-wide information on Docker, run:

$ sudo docker info

Step 4 — Intro to Docker Images

Docker containers are built from Docker images.

What is a Docker image? To put it simply, a Docker image is basically a template that you use for your container. It’s a binary that includes all the requirements and instructions necessary to run a Docker container.

Most images are kept at Docker Hub, which is a Docker registry managed by Docker, the company behind the Docker project. By default, Docker is configured to automatically pull images from there when you request them. It’s easy to use and a great resource featuring excellent Docker images. There you’ll find most applications and Linux distributions that you need.

Check if you have access and can download images from Docker Hub with the mandatory `hello world` example:

$ sudo docker run hello-world

The output will look something like this:

sudo 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.

As you may tell from the output, `docker` was initially unable to find the `hello-world` image locally, so it downloaded it from Docker Hub, created a container from it, and ran the application within the container, which displayed the `Hello from Docker […]` message.

Searching for Docker Images

You can also search for various images, using the `search` subcommand. The script will search Docker Hub and list all images matching the string you used:

$ sudo docker search wordpress

Output

$ sudo docker search wordpress
NAME                                                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
wordpress                                           The WordPress rich content management system…   2652                [OK]                
bitnami/wordpress                                   Bitnami Docker Image for WordPress              95                                      [OK]
appcontainers/wordpress                             Centos/Debian Based Customizable WordPress C…   34                                      [OK]
etopian/alpine-php-wordpress                        Alpine WordPress Nginx PHP-FPM WP-CLI           18                                      [OK]
centurylink/wordpress                               WordPress image with MySQL removed.             14                                      [OK]
raulr/nginx-wordpress                               Nginx front-end for the official wordpress:f…   11                                      [OK]
1and1internet/ubuntu-16-nginx-php-5.6-wordpress-4   ubuntu-16-nginx-php-5.6-wordpress-4             6                                       [OK]
dalareo/wordpress-ldap                              WordPress images with LDAP support automatic…   6                                       [OK]
withinboredom/scalable-wordpress                    An easy to scale WordPress                      5                                       [OK]
1and1internet/ubuntu-16-nginx-php-7.1-wordpress-4   ubuntu-16-nginx-php-7.1-wordpress-4             3                                       [OK]
julianxhokaxhiu/docker-awesome-wordpress            A Docker that combines all the most awesome …   2                                       [OK]
wodby/wordpress-nginx                               Nginx for WordPress                             2                                       [OK]
gwee/wordpress-sendmail-docker                      wordpress with sendmail                         2                                       [OK]
wodby/wordpress-php                                 PHP for WordPress                               2                                       [OK]
dsteinkopf/wordpress                                wordpress clone plus some php extensions        1                                       [OK]
julianxhokaxhiu/docker-wordpress-ldaps              WordPress Docker image with LDAPS support       1                                       [OK]
arm64v8/wordpress                                   The WordPress rich content management system…   1                                       
bakudankun/wordpress-ja                             WordPress Japanese Edition forked from offic…   1                                       [OK]
owncloud/wordpress                                  WordPress image for ownCloud websites           1                                       
apsl/wordpress                                      WordPress on LAMP managed with circus. Wordp…   1                                       [OK]
davask/d-wordpress                                  Dockerfile for wordpress                        0                                       [OK]
itherz/wordpress                                    WordPress                                       0                                       [OK]
erikzenker/wordpress                                wordpress docker image                          0                                       
ansibleplaybookbundle/wordpress-ha-apb              An APB which deploys WordPress HA               0                                       [OK]
mattti/wordpress                                    WordPress adjusted to my own needs              0                                       [OK]

OK in the OFFICIAL column indicates that the image is created and supported by the company behind the software

Downloading (Pulling) Docker Images

If you decide what image you want to use, you can download it to your machine by using the `pull` subcommand.

For example, we’ll download the official WordPress image. To do this run:

$ sudo docker pull wordpress

After it finishes downloading the image, the output will look something like this:

$ sudo docker pull centos
Using default tag: latest
latest: Pulling from library/centos
aeb7866da422: Pull complete 
Digest: sha256:67dad89757a55bfdfabec8abd0e22f8c7c12a1856514726470228063ed86593b
Status: Downloaded newer image for centos:latest

After the image is downloaded, you can run a container using it using the `run` command, as we've done in the `hello-world` example. If the image has not yet been downloaded, Docker will attempt to pull it from Docker Hub, and then run a container using it.

Listing Docker Images

To list all of our downloaded images just run:

$ sudo docker images

Example output

sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              75835a67d134        6 weeks ago         200MB
hello-world         latest              4ab4c602aa5e        2 months ago        1.84kB

Further in this tutorial, we'll see how downloaded images can be modified and generated into new images, which we can then upload to Docker Hub or other Docker registries.

Step 5 — Intro to Docker Containers

Earlier we played around with the `hello-world` container. We downloaded the image and used it to run the `hello-world` container which just displayed a message and exited after showing us the message. That was just a basic example. Docker containers can do more than that, and we can use them interactively, just like we would with a VPS, but much more resource friendly.

Let's see an example of how a container can be similar to a VPS. Given the fact that we're using Ubuntu, let's go a little crazy and run a container using the latest image of CentOS. Don't worry if you've never used CentOS - what we're doing is similar to what we'd do on Ubuntu.

We'll use the combination of the `-i` and `-t` switches to get interactive shell access to the container:

$ sudo docker run -it centos

Docker will most likely not find the image on your machine and pull it from Docker Hub. After it's downloaded and the container is run, your command prompt will change, reflecting the fact that you're working inside the container:

[root@35e04744a977 /]#

The seemingly random sequence of letters and numbers, `35e04744a977`, represents the container ID. We use that to identify the container and need it should we want to remove the container.

Now let's run some basic commands, like update the package database inside the container. On CentOS, to do this, we use `yum` instead of `apt`. You also don't need to use `sudo`, as you're now acting as `root` in this container.

# yum update

Now let's install an application on it, such as `PHP`:

# yum install php

When the installation, if I check the version, I get the following output:

php -v
PHP 5.4.16 (cli) (built: Apr 12 2018 19:02:01)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

Any changes you make in the container only apply to that container.

To exit the container just run `exit`.

List Docker Containers

After you've used Docker for a while, you'll most likely be managing a few Docker containers, active and inactive.

To view your active containers run the following:

$ sudo docker ps

Since we've got our demo containers inactive, we'll get the following output:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

So far we've run two containers. One from the `hello-world` image, and the other from the `centos` image, but now they're both stopped.

To view all of the containers, active and inactive, run the following:

$ sudo docker ps -a

This is the output I'm seeing:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
35e04744a977        centos              "/bin/bash"         6 hours ago         Exited (137) 3 hours ago                       pensive_northcutt
82d53d646a6c        hello-world         "/hello"            19 hours ago        Exited (0) 19 hours ago                        frosty_allen

To view the latest created container, run the following:

docker ps -l

Output

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
35e04744a977        centos              "/bin/bash"         6 hours ago         Exited (137) 3 hours ago                       pensive_northcutt

Start/Stop Docker Containers

To start a stopped container use `docker start`, followed by the container's ID (`35e04744a977`) or name (`pensive_northcutt`). In our example I'll start by using its' name:

$ sudo docker start pensive_northcutt

Now let's see if it started by listing our active containers:

$ sudo docker ps

Output

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
35e04744a977        centos              "/bin/bash"         9 hours ago         Up 33 seconds                           pensive_northcutt

To stop the running container, you run `docker stop` followed by the container name or ID:

$ sudo docker stop pensive_northcutt

Useful Basic Docker Commands

Running commands inside an active

When you use `docker start` you'll notice that it's started, but you're not interacting with it, such as when you first ran it. To run commands inside it, you can use `docker exec -it`, followed by the ID or name of the container, and followed by `/bin/bash`. You'll notice your prompt change, letting you know that you've opened up a new terminal in it:

sudo docker exec -it pensive_northcutt /bin/bash
[root@35e04744a977 /]#

The `-t` switch opens a terminal, the `-i` switch makes it interactive, and the `/bin/bash` option opens a bash shell to the running container.

Exit a container without stopping it

You may find yourself needing to exit the container but wanting it to remain active. To do this, you can type `Ctrl+P` followed by `Ctrl+Q`. You'll see something like the following output:

[root@35e04744a977 /]# read escape sequence

Renaming a container

To rename a container, you can use `docker rename`, followed by the current name or ID of the container, and then the desired name.

For example, to better organize my containers, I may want to rename my container named `pensive_northcutt` to a name similar to the naming convention that Docker seems to use, so I'll call it `mr_tiny_nipples`.

$ sudo docker rename pensive_northcutt mr_tiny_nipples

If I run `sudo docker ps` (because my container is still active), I get the output:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
35e04744a977        centos              "/bin/bash"         10 hours ago        Up 8 minutes                            mr_tiny_nipples

Additionally, you can give a container a name of your choosing, when creating it, by using the `--name` switch.

Remove Docker Containers

When you no longer have use for a container you can remove it by using `docker rm`, followed by its' name or ID:

$ sudo rm mr_tiny_tipples

Conclusion

In this tutorial, you've hopefully learned to install Docker and a little about using it and managing containers. We've just covered a few of the basics, however, and there's a lot more you can do with it. There's a reason some of the top companies in the world leverage Docker, and we'll try to cover more in future tutorials.

To learn more about Docker, we recommend that you check out the official Docker documentation.

Should you encounter any issues when following this tutorial, or would like specific aspects covered, don't hesitate to contact us and we'll get back to you as soon as possible.

If you're in need of a VPS to run Docker on, then feel free to check out our KVM SSD VPS plans. Our VPS offer starts at 2GB RAM + 10GB SSD at only $5.99/mo.

LIMITED TIME SPECIAL 💀

Enter your email below to get 20% OFF on any of our Linux VPS plans and receive weekly deals on our services!