skip to main content

Что такое Docker?

js

Кратко 🔗

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

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

Как начать 🔗

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

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

docker --version

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

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

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

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

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

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

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

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 restart

# Команда для остановки контейнера
docker container stop

# Команда для постановки контейнера на паузу
docker container pause

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

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

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

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

В работе 🔗

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

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

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

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

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

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

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

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 .

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

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

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

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

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

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

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

#!/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 <параметры>