Собачка Дока в образе кита из логотипа Докера
Иллюстрация: Кира Кустова

Что такое Docker

Разбираемся, какие задачи решает докер, как он устроен и как запустить свой первый контейнер.

Время чтения: 10 мин

Кратко

Скопировано

Docker — это технология, которая позволяет создавать и использовать приложения в «родном» окружении. В основе Docker лежит идея: если приложение работает у вас, то оно должно работать где угодно. Способ этого добиться очень простой — нужно упаковать настройки окружения вместе с приложением.

Docker чаще всего применяется для развёртывания серверных приложений, но может использоваться и в мире фронтенда для:

Как начать

Скопировано

Установите Docker:

Запустите Docker и проверьте его работоспособность с помощью графического интерфейса Dashboard (для Mac или Windows) или команды в терминале (для всех операционных систем):

        
          
          docker --version
          docker --version

        
        
          
        
      

У создателей Docker есть готовая демка, которую можно запустить командой:

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

        
        
          
        
      

Теперь можно открыть в браузере документацию Docker по адресу http://localhost.

Как понять

Скопировано

Запуск готового веб-приложения — наиболее популярный сценарий использования. Демка Docker — самое простое, что можно сделать «из коробки». Вам не пришлось устанавливать и запускать веб-сервер, не пришлось разбираться с какими-либо настройками, вы не трудились устанавливать у себя Node.js и не столкнулись ни с какими сложностями. Представьте, что вы передали проект другому разработчику, и вам не приходится возиться с тем, чтобы проект запускался, не приходится говорить: «А у меня все работало 😞»

Без Docker вы, скорее всего, действовали бы так:

  1. Узнали операционную систему на компьютере разработчика.
  2. Сформировали сценарий или инструкцию настройки окружения.
  3. Протестировали, как развёртывается ваше приложение.
  4. Передали приложение разработчику, и ждали результаты.

Ситуация будет ещё сложнее, если вы и другой разработчик используете разные операционные системы. С Docker все намного проще! Вы создаёте конфигурацию, и если она работает у вас, то заработает у всех.

Docker упаковывает приложение так, что будет счастлив любой, кто его получит 😇

Давайте разберёмся, как это происходит. Что должен делать Docker с вашим приложением, какое окружение он должен подготовить?

Рассмотрим пример с демкой от создателей Docker. Когда вы выполнили команду docker run, произошло следующее:

  1. Docker нашёл и загрузил приложение с именем docker/getting-started из реестра приложений Docker Hub. Приложение уже было заботливо упаковано со всеми необходимыми ему утилитами и программами. Такая упаковка называется образ (Docker Image). Образ обычно содержит в себе операционную систему на базе Linux, стартовую конфигурацию для установки служб, утилит, приложений, зависимостей проекта — все это называется окружением приложения.
  2. Docker создал контейнер (Docker Container) на основе образа. Контейнер — это конкретный экземпляр образа на вашем компьютере. Отношение «образ — контейнер» примерно такое же, как у пары «класс — объект класса» в ООП.
  3. Docker запустил контейнер с веб-сервером Nginx внутри, и веб-приложение «Справка по Docker» заработало. Для вашей операционной системы запустить контейнер — это все равно что запустить любое приложение или сервис.

Вы просто начали использовать веб-приложение, никаких сложностей.

Модель стандартного применения Docker

Перед тем, как мы научимся готовить образ сами, необходимо разобраться с терминами. Лучше сделать это на берегу 😎

Важные службы

Скопировано

Движок Docker Engine — приложение для управления объектами Docker. Оно включает в себя три компонента:

  1. сервер (Docker Daemon);
  2. интерфейс (Docker API);
  3. консольный клиент (Docker CLI).

Ваш компьютер называется Docker Host. Все операции, которые мы выполняем в интерфейсе или через консоль, выполняются сервером через API движка.

Docker Desktop — пакет приложений с графическим интерфейсом, включающий специальную виртуальную машину для работы с движком, визуальный интерфейс (Dashboard), консольный клиент, инструменты для работы с реестром Docker Hub и пр.

Для платформы Mac и Windows невозможно использовать Docker Engine напрямую, необходимо запустить виртуальную машину. Docker Desktop содержит такую виртуальную машину. Все процессы в ней оптимизированы, контейнеры работают быстрее, но определённые ограничения все равно присутствуют.

Объекты Docker

Скопировано

Образ (Docker Image) — прототип будущего контейнера, содержащий операционную систему, приложение или проект для сборки приложения. Образы состоят из слоёв. Каждый новый слой — это надстройка над предыдущим. Слои должны надстраиваться поверх базового образа, формируя новый. Например, базовым образом может быть образ операционной системы.

Слои образа описываются в специальных файлах конфигурации. Как правило, для этого используется Dockerfile. Конфигурационный файл всегда начинается с указания базового образа, имя которого прописывается после директивы FROM. Дальше могут идти разные надстройки (новые слои) образа. Вы можете задать рабочую папку проекта с помощью директивы WORKDIR, скопировать файлы в эту рабочую папку директивой COPY, запустить выполнение команды или нескольких команд в терминале директивой RUN. Пример конфигурации:

        
          
          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

        
        
          
        
      

Контейнер (Docker Container) — уже собранное и запущенное приложение в изолированном окружении, которое формируется послойно, в соответствии с образом. Каждый новый слой расширяет функциональность предыдущего, формируя стек используемых инструментов, платформ и настроек системных служб. Файловая система контейнера тоже стековая (Union File Systems). Каталоги и файлы отдельного слоя образа накладываются друг на друга, образуя единое целое.

Том (Docker Volume) — папка, которую можно подключить (говорят «примонтировать») к контейнерам. Папка может быть связана с конкретной папкой на вашем компьютере, а может быть как бы сетевой для контейнеров на вашем компьютере. Тома необходимы для хранения файлов конфигурации, критических с точки зрения безопасности, файлов баз данных, файлов, которые нельзя удалять после окончания работы приложения.

Сеть (Docker Network) — виртуальная локальная сеть, которая позволяет совместно использовать несколько запущенных контейнеров и соединять запущенный контейнер с вашим компьютером. В основном вы будете использовать три режима работы сетевой инфраструктуры Docker:

  1. bridge — когда контейнеры могут взаимодействовать между собой как веб-сервер и база данных.
  2. host — для доступа к локальному сетевому окружению на вашем компьютере.
  3. none — сеть для контейнеров полностью отключена.

Инструменты

Скопировано

Docker Hub (реестр) — официальный реестр образов.

Опубликованные образы хранятся в Docker Hub. Существуют и другие публичные реестры образов:

Предпочитайте официальные образы Docker, которые обновляются самой компанией. Они относительно безопасны. Для фронтенд-разработчика могут быть интересны:

Docker CLI — консольный клиент, позволяющий управлять Docker через интерфейс командной строки.

Консольный клиент содержит команды для управления объектами Docker. Список основных команд:

Как пользоваться

Скопировано

Ключи командного интерфейса Docker CLI хорошо проработаны и похожи на консольные команды в bash. Например, дополнительный ключ prune позволяет удалять неиспользуемые объекты. Ключ rm служит для удаления, а ключ ls для просмотра объектов. Объекты Docker в обязательном порядке имеют уникальное имя. Если вы не именуете объект специально, то имя объекта формируется с помощью хэш-функции. Если вы попытаетесь создать объект одного и того же типа с уже использованным именем, в этом вам будет отказано. Как же пользоваться консольным клиентом?

Мониторинг запущенных контейнеров

Скопировано
  • docker ps — просмотр запущенных контейнеров.
  • docker ps -a — ключ -a выводит и запущенные, и остановленные контейнеры.
  • docker ps -s — ключ -s выводит дисковое пространство, используемое каждым запущенным контейнером.
  • docker ps -f name=hello — ключ -f фильтрует список контейнеров по имени, например, hello.

Полный список ключей для команды docker ps доступен в документации.

Запуск контейнеров

Скопировано

Для запуска контейнера, который доступен локально или на Docker Hub, выполните команду:

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

        
        
          
        
      

Ключ --name используется для установки имени запущенного контейнера. Ключи -i и -t указывают, что для запуска контейнера будет использоваться стандартный поток ввода и терминал TTY соответственно. Для того чтобы при запуске контейнера примонтировать том, который будет связан с папкой на вашем компьютере, а потом получить доступ к контейнеру через терминал, выполните команду:

        
          
          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

        
        
          
        
      

Полный список ключей для команды docker run доступен в документации.

Управление образами

Скопировано

Вы можете получить список всех доступных локально образов с помощью команды:

        
          
          docker image ls
          docker image ls

        
        
          
        
      

Ключи prune, rm действуют обычным способом, позволяя удалить неиспользуемые или конкретные образы соответственно. Для работы с реестром необходимо использовать следующие команды:

  • docker image pull hello — загрузка образа с именем hello из реестра;
  • docker image push hello — отправка образа с именем hello в реестр;
  • docker image inspect hello — полная информация о контейнере hello;
  • docker image build — собрать контейнер из текущей папки с учётом Dockerfile.

Полный список ключей для команды docker image доступен в документации.

Управление контейнерами

Скопировано

Наиболее используемыми командами будут команды запуска и остановки контейнеров.

Команда для запуска контейнера:

        
          
          docker container start
          docker container start

        
        
          
        
      

Команда для перезапуска контейнера:

        
          
          docker container restart
          docker container restart

        
        
          
        
      

Команда для остановки контейнера:

        
          
          docker container stop
          docker container stop

        
        
          
        
      

Команда для постановки контейнера на паузу:

        
          
          docker container pause
          docker container pause

        
        
          
        
      

Полный список ключей для команды docker container доступен в документации.

Управление томами

Скопировано
  • docker volume ls — вывод всех томов.
  • docker volume ls -f name=hello — вывод всех томов с фильтрацией по имени, например, hello.
  • docker volume create hello — создание нового тома, например, hello.
  • docker volume inspect hello — исчерпывающая информация о томе.

Полный список ключей для команды docker volume доступен в документации.

На практике

Скопировано

Игорь Коровченко советует

Скопировано

Рассмотрим несколько примеров, когда Docker может пригодиться.

Например, вы можете запустить свой сервер Minecraft одной командой:

        
          
          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

        
        
          
        
      

Подобных образов достаточно много на Docker Hub. Для ежедневной работы полезнее будут образы с популярными инструментами или сервисами, например:

  1. Веб-сервер Nginx;
  2. Веб-сервер Apache;
  3. Связка базы данных MongoDB и фреймворка Express;
  4. Сервис Sentry для мониторинга ошибок в браузерах;
  5. Линтер SonarQube с поддержкой большого количества языков;
  6. Инструмент для оценки качества страниц Google Lighthouse.

Попробовать движок сайта без установки

Скопировано

Иногда нам нужно посмотреть, как работает та или иная CMS (Content Management System). CMS — это веб-приложение, которое позволяет управлять содержимым сайта и внешним видом через веб-интерфейс. Чтобы такое приложение заработало, нужно установить базу данных, веб-сервер и интерпретатор языка, на котором написана CMS. Но можно и ничего не устанавливать! Docker позволяет запустить CMS одной командой. После запуска вы сможете работать с CMS через веб-интерфейс в своём браузере или через терминал, если понадобится доступ к файлам и ресурсам приложения.

Запускаем Wordpress одной командой:

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

        
        
          
        
      

Запускаем Drupal командой:

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

        
        
          
        
      

Попробовать новый фреймворк

Скопировано

Фронтенд-разработчику Docker даёт возможность попробовать разные технологии без траты времени на установку и настройку. Например, упаковать приложение на платформе Node.js в контейнер не составит большого труда. Добавьте в проект файл Dockerfile:

        
          
          FROM node:12# Создание директории приложенияWORKDIR /app# Установка зависимостей, учитывая package.json и package-lock.jsonCOPY package*.json ./RUN npm i# Сборка проекта, если есть необходимостьRUN npm ci --only=production# Копирование исходного кода приложенияCOPY . .EXPOSE 8080CMD [ "node", "app.js" ]
          FROM node:12

# Создание директории приложения
WORKDIR /app

# Установка зависимостей, учитывая package.json и package-lock.json
COPY package*.json ./

RUN npm i

# Сборка проекта, если есть необходимость
RUN npm ci --only=production

# Копирование исходного кода приложения
COPY . .

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

        
        
          
        
      

После этого выполните команду:

        
          
          docker build .
          docker build .

        
        
          
        
      

Точка в конце означает, что образ собирается из текущей папки. По умолчанию для сборки используется файл с именем Dockerfile. После ключа -t можно задать имя образа:

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

        
        
          
        
      

После сборки вы сможете запустить контейнер с приложением внутри него.

Вы можете начать проект на Angular, React или Vue, полностью переместив разработку внутрь контейнера. Популярные редакторы так или иначе поддерживают эту возможность. Такой подход позволит учитывать все особенности и тонкости настройки проекта не только вам, как автору, но и тем, кто будет работать с проектом в будущем.

Не бойтесь, что каждый образ, каждая настройка будут занимать много места. Переиспользование — благо, от которого не уходят и разработчики Docker. Все слои образа, которые уже есть на вашем компьютере, будут переиспользованы. Тем не менее, за образами и контейнерами нужно следить, чтобы хранилище не разрасталось, а оперативная память не заканчивалась. Все это можно настроить с помощью установки ограничений.

Готовить картинки и другие ресурсы

Скопировано

Интересным примером использования Docker является подготовка ресурсов веб-приложения.

С помощью утилиты ImageMagick можно работать с картинками в консоли. Вы можете установить её на свой компьютер или использовать готовый образ. Например, чтобы изменить размеры картинки, выполните команду:

        
          
          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

        
        
          
        
      

Необходимо поработать со шрифтами? Например, популярный инструмент glyphhanger требует нетривиальной установки. Но есть готовый Docker-образ, и с его помощью можно запустить эту утилиту командой:

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

        
        
          
        
      

Можно также заменить эту длинную команду алиасом в файле настроек терминала:

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

        
        
          
        
      

Предварительно надо написать соответствующий скрипт в файле ~/.docker-glyphhanger/docker-glyphhanger.sh:

        
          
          #!/bin/bash# Проверка работающей службы Dockerif ! (command -v docker >> /dev/null)then    echo "docker command not found!";    exit 1;fi# Проверка нужного образа в локальном хранилищеif !(docker image ls | grep wopolow/glyphhanger >> /dev/null)then    docker pull wopolow/glyphhangerfi# Запуск утилиты glyphhangerif ! [ -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

# Проверка работающей службы Docker
if ! (command -v docker >> /dev/null)
then
    echo "docker command not found!";
    exit 1;
fi

# Проверка нужного образа в локальном хранилище
if !(docker image ls | grep wopolow/glyphhanger >> /dev/null)
then
    docker pull wopolow/glyphhanger
fi

# Запуск утилиты glyphhanger
if ! [ -z "$1" ] && [ $1 != "install" ]
then
    docker container run --rm -v $(pwd):/hwd wopolow/glyphhanger glyphhanger $@
else
    echo "docker-glyphhanger: internal installation complete";
fi

        
        
          
        
      

После этого вы сможете производить всякие манипуляции со шрифтами простой командой, используя параметры утилиты glyphhanger:

        
          
          glyphy <параметры>
          glyphy <параметры>

        
        
          
        
      

На собеседовании

Скопировано
Задать вопрос в рубрику
🤚 Я знаю ответ

Редакция
Игорь Коровченко  отвечает

Скопировано

Обычно жизненный цикл контейнера состоит из следующей последовательности состояний:

  1. Создание контейнера
  2. Работа контейнера
  3. Приостановка контейнера
  4. Возобновление работы контейнера
  5. Запуск контейнера
  6. Остановка контейнера
  7. Перезапуск контейнера
  8. Принудительная остановка контейнера
  9. Удаление контейнера

На практике встречаются и более сложные случаи, поэтому жизненный цикл контейнера лучше представить с помощью диаграммы:

Схема жизненного цикла контейнера Docker с указанием команд управления

На этой диаграмме показаны не только состояния и пути перехода из одного состояния в другое, но и команды, которые позволяют пользователю их менять.