Doka the dog in the form of a whale from the Docker logo

What is Docker

Let's figure out what problems Docker solves, how it works, and how to launch your first container.

Time to read: 12 min

In Brief

Docker is a technology that allows you to create and use applications in their "native" environment. The core idea behind Docker is: if an application works for you, it should work anywhere. The way to achieve this is very simple—you need to package the environment settings along with the application.

Docker is most commonly used for deploying server applications, but it can also be used in the frontend world for:

How to Get Started

Install Docker:

Start Docker and check its operation via the graphical interface Dashboard (for Mac or Windows) or a command in the terminal (for all operating systems):

        
          
          docker --version
          docker --version

        
        
          
        
      

The creators of Docker have a ready-made demo that you can launch with the command:

        
          
          docker run -d -p 80:80 docker/getting-started
          docker run -d -p 80:80 docker/getting-started

        
        
          
        
      

Now you can open the Docker documentation in your browser at http://localhost.

How to Understand

Launching a ready web application is the most popular use case. The Docker demo is the simplest thing you can do "out of the box." You didn't have to install and launch a web server, didn't have to deal with any settings, didn't struggle to install Node.js, and faced no complications whatsoever. Imagine that you handed the project to another developer, and you don't have to fuss with getting the project to run—you don’t have to say, "But it worked for me 😞"

Without Docker, you would most likely act as follows:

  1. Identify the operating system on the developer's computer.
  2. Formulate a script or instructions for setting up the environment.
  3. Test how your application is deployed.
  4. Hand over the application to the developer and wait for results.

The situation would be even more complicated if you and the other developer used different operating systems. With Docker, everything is much simpler! You create a configuration, and if it works for you, it will work for everyone.

Docker packages the application in a way that anyone who receives it will be happy 😇

Let’s figure out how this happens. What should Docker do with your application, what environment should it prepare?

Consider the example with the demo from the creators of Docker. When you executed the docker run command, the following happened:

  1. Docker found and downloaded the application named docker/getting-started from the Docker Hub application registry. The application had already been carefully packaged with all the necessary utilities and programs. This packaging is called an image (Docker Image). An image usually contains a Linux-based operating system, a starter configuration for installing services, utilities, applications, and project dependencies—all of this is called the application environment.
  2. Docker created a container (Docker Container) based on the image. A container is a specific instance of an image on your computer. The relationship between "image — container" is roughly the same as the pair "class — object of a class" in OOP.
  3. Docker started the container with the Nginx web server inside, and the web application "Docker Documentation" began running. For your operating system, starting a container is the same as starting any application or service.

You simply began using the web application, no complications.

Standard Docker Usage Model

Before we learn how to prepare an image ourselves, it's necessary to understand the terminology. It's better to do this ahead of time 😎

Important Services

Docker Engine — an application for managing Docker objects. It includes three components:

  1. server (Docker Daemon);
  2. interface (Docker API);
  3. command-line client (Docker CLI).

Your computer is called the Docker Host. All operations that we perform in the interface or through the console are executed by the server through the engine API.

Docker Desktop — a package of applications with a graphical interface, including a special virtual machine for working with the engine, a visual interface (Dashboard), a command-line client, tools for working with the Docker Hub registry, etc.

For Mac and Windows platforms, it is not possible to use Docker Engine directly; it is necessary to start a virtual machine. Docker Desktop contains such a virtual machine. All processes within it are optimized, containers run faster, but certain limitations still exist.

Docker Objects

Image (Docker Image) — a prototype of a future container, containing an operating system, an application, or a project for building an application. Images consist of layers. Each new layer is an addition to the previous one. Layers must be built on top of a base image, forming a new one. For example, a base image could be an operating system image.

Image layers are described in special configuration files. Typically, a Dockerfile is used for this purpose. The configuration file always starts with a specification of the base image, the name of which is written after the FROM directive. Next, various additions (new layers) of the image may follow. You can specify the project working directory using the WORKDIR directive, copy files to this working directory using the COPY directive, and run commands in the terminal using the RUN directive. Example configuration:

        
          
          FROM ubuntu:18.04WORKDIR /appCOPY . .RUN apt-get update && apt-get upgrade
          FROM ubuntu:18.04
WORKDIR /app
COPY . .
RUN apt-get update && apt-get upgrade

        
        
          
        
      

Container (Docker Container) — a pre-assembled and running application in an isolated environment, which is formed layer by layer, in accordance with the image. Each new layer extends the functionality of the previous one, forming a stack of used tools, platforms, and system service settings. The file system of the container is also stackable (Union File Systems). Directories and files from separate layers of the image overlap one another, forming a unified whole.

Volume (Docker Volume) — a folder that can be attached (referred to as "mounted") to containers. The folder can be linked to a specific folder on your computer or can be a sort of network folder for containers on your computer. Volumes are necessary for storing configuration files that are critical from a security perspective, database files, files that cannot be deleted after the application has finished running.

Network (Docker Network) — a virtual local network that allows multiple running containers to share and connect a running container with your computer. Primarily, you will use three operational modes of Docker's network infrastructure:

  1. bridge — when containers can interact with each other, such as a web server and a database.
  2. host — for access to the local network environment on your computer.
  3. none — the network for containers is completely disabled.

Tools

Docker Hub (registry) — the official image registry.

Published images are stored in Docker Hub. There are other public image registries:

Prefer official Docker images, which are updated by the company itself. They are relatively safe. For frontend developers, the following may be of interest:

Docker CLI — a command-line client that allows you to manage Docker from the command line interface.

The command-line client contains commands for managing Docker objects. A list of basic commands includes:

How to Use

The command-line interface keys of Docker CLI are well thought out and resemble console commands in bash. For example, the additional key prune allows you to delete unused objects. The key rm is used for deletion, and the key ls for viewing objects. Docker objects must have a unique name. If you do not name an object explicitly, its name will be formed using a hash function. If you try to create an object of the same type with an already used name, it will be denied. How to use the command-line client?

Monitoring Running Containers

  • docker ps — view running containers.
  • docker ps -a — the -a flag shows both running and stopped containers.
  • docker ps -s — the -s flag shows the disk space used by each running container.
  • docker ps -f name=hello — the -f flag filters the list of containers by name, e.g., hello.

The complete list of flags for the docker ps command is available in the documentation.

Running Containers

To start a container that is available locally or on Docker Hub, execute the command:

        
          
          docker run --name test -i -t hello
          docker run --name test -i -t hello

        
        
          
        
      

The --name flag is used to set the name of the running container. The -i and -t flags indicate that the standard input stream and TTY terminal will be used to start the container, respectively. To mount a volume linked to a folder on your computer when starting the container and then access the container through the terminal, execute the command:

        
          
          docker run -t -i --mount type=bind,src=/data,dst=/data hello bash
          docker run -t -i --mount type=bind,src=/data,dst=/data hello bash

        
        
          
        
      

The complete list of flags for the docker run command is available in the documentation.

Managing Images

You can list all available local images using the command:

        
          
          docker image ls
          docker image ls

        
        
          
        
      

The prune, rm flags work as expected, allowing you to delete unused or specific images, respectively. To work with the registry, the following commands are necessary:

  • docker image pull hello — download the image named hello from the registry;
  • docker image push hello — upload the image named hello to the registry;
  • docker image inspect hello — complete information about the container hello;
  • docker image build — build the container from the current folder taking into account the Dockerfile.

The complete list of flags for the docker image command is available in the documentation.

Managing Containers

The most commonly used commands will be the commands to start and stop containers.

Command to start a container:

        
          
          docker container start
          docker container start

        
        
          
        
      

Command to restart a container:

        
          
          docker container restart
          docker container restart

        
        
          
        
      

Command to stop a container:

        
          
          docker container stop
          docker container stop

        
        
          
        
      

Command to pause a container:

        
          
          docker container pause
          docker container pause

        
        
          
        
      

The complete list of flags for the docker container command is available in the documentation.

Managing Volumes

  • docker volume ls — list all volumes.
  • docker volume ls -f name=hello — list all volumes filtered by name, e.g., hello.
  • docker volume create hello — create a new volume, e.g., hello.
  • docker volume inspect hello — comprehensive information about the volume.

The complete list of flags for the docker volume command is available in the documentation.

In practice

Advice 1

Let's consider several examples where Docker can be useful.

For instance, you can launch your Minecraft server with a single command:

        
          
          docker run -e EULA=TRUE -d -p 25565:25565 --name mc itzg/minecraft-server
          docker run -e EULA=TRUE -d -p 25565:25565 --name mc itzg/minecraft-server

        
        
          
        
      

There are many such images available on Docker Hub. For daily work, images with popular tools or services will be more useful, such as:

  1. Web server Nginx;
  2. Web server Apache;
  3. Combination of MongoDB database and Express framework;
  4. Sentry service for monitoring errors in browsers;
  5. SonarQube linter with support for many languages;
  6. Google Lighthouse tool for assessing page quality.

Try the website engine without installation

Sometimes we need to see how a particular CMS (Content Management System) works. A CMS is a web application that allows you to manage website content and appearance through a web interface. To make such an application work, you need to install a database, a web server, and a language interpreter on which the CMS is written. But you don't have to install anything! Docker allows you to run a CMS with a single command. After starting, you will be able to work with the CMS through the web interface in your browser or through the terminal if you need access to the application files and resources.

We start Wordpress with a single command:

        
          
          docker run --name some-wordpress -p 8080:80 -d wordpress
          docker run --name some-wordpress -p 8080:80 -d wordpress

        
        
          
        
      

We start Drupal with a command:

        
          
          docker run --name some-drupal -p 8080:80 -d drupal
          docker run --name some-drupal -p 8080:80 -d drupal

        
        
          
        
      

Try a new framework

For frontend developers, Docker gives the opportunity to try various technologies without wasting time on installation and setup. For example, packaging an application on the Node.js platform into a container is not a big problem. Add a Dockerfile to the project:

        
          
          FROM node:12# Create application directoryWORKDIR /app# Install dependencies, considering package.json and package-lock.jsonCOPY package*.json ./RUN npm i# Build the project if necessaryRUN npm ci --only=production# Copy the source code of the applicationCOPY . .EXPOSE 8080CMD [ "node", "app.js" ]
          FROM node:12

# Create application directory
WORKDIR /app

# Install dependencies, considering package.json and package-lock.json
COPY package*.json ./

RUN npm i

# Build the project if necessary
RUN npm ci --only=production

# Copy the source code of the application
COPY . .

EXPOSE 8080
CMD [ "node", "app.js" ]

        
        
          
        
      

After that, run the command:

        
          
          docker build .
          docker build .

        
        
          
        
      

The dot at the end means that the image is built from the current folder. By default, the file named Dockerfile is used for building. After the -t key, you can specify the name of the image:

        
          
          docker build -t app .
          docker build -t app .

        
        
          
        
      

After the build, you can run a container with the application inside it.

You can start a project on Angular, React, or Vue, completely moving development inside the container. Popular editors support this feature in one way or another. This approach will take into account all the features and nuances of configuring the project not only for you as the author but also for those who will work on the project in the future.

Don't be afraid that each image, each setting will take up a lot of space. Reuse is a good practice, and even Docker developers don't get away from it. All image layers that are already on your computer will be reused. However, you need to monitor images and containers to prevent storage from ballooning and running out of RAM. All of this can be configured using setting constraints.

Prepare images and other resources

An interesting example of using Docker is the preparation of resources for a web application.

Using the ImageMagick utility, you can work with images in the console. You can install it on your computer or use a ready-made image. For example, to change the size of an image, run the command:

        
          
          docker run -v /your/images:/imgs dpokidov/imagemagick /imgs/sample.png -resize 100x100 /imgs/resized-sample.png
          docker run -v /your/images:/imgs dpokidov/imagemagick /imgs/sample.png -resize 100x100 /imgs/resized-sample.png

        
        
          
        
      

Do you need to work with fonts? For example, the popular tool glyphhanger requires a non-trivial installation. But there's a ready-made Docker image, and you can run this utility with the command:

        
          
          docker container run --rm -v $(pwd):/hwd wopolow/glyphhanger glyphhanger
          docker container run --rm -v $(pwd):/hwd wopolow/glyphhanger glyphhanger

        
        
          
        
      

You can also replace this long command with an alias in the terminal configuration file:

        
          
          alias glyphy='~/.docker-glyphhanger/docker-glyphhanger.sh'
          alias glyphy='~/.docker-glyphhanger/docker-glyphhanger.sh'

        
        
          
        
      

First, you need to write the corresponding script in the file ~/.docker-glyphhanger/docker-glyphhanger.sh:

        
          
          #!/bin/bash# Check for running Docker serviceif ! (command -v docker >> /dev/null)then    echo "docker command not found!";    exit 1;fi# Check for the required image in local storageif !(docker image ls | grep wopolow/glyphhanger >> /dev/null)then    docker pull wopolow/glyphhangerfi# Run the glyphhanger utilityif ! [ -z "$1" ] && [ $1 != "install" ]then    docker container run --rm -v $(pwd):/hwd wopolow/glyphhanger glyphhanger $@else    echo "docker-glyphhanger: internal installation complete";fi
          #!/bin/bash

# Check for running Docker service
if ! (command -v docker >> /dev/null)
then
    echo "docker command not found!";
    exit 1;
fi

# Check for the required image in local storage
if !(docker image ls | grep wopolow/glyphhanger >> /dev/null)
then
    docker pull wopolow/glyphhanger
fi

# Run the glyphhanger utility
if ! [ -z "$1" ] && [ $1 != "install" ]
then
    docker container run --rm -v $(pwd):/hwd wopolow/glyphhanger glyphhanger $@
else
    echo "docker-glyphhanger: internal installation complete";
fi

        
        
          
        
      

After that, you will be able to perform various manipulations with fonts using the simple command, using the options of the glyphhanger utility:

        
          
          glyphy <parameters>
          glyphy <parameters>