Установка и использование Docker Compose на Ubuntu 14.04

Docker это отличный инструмент, но чтобы воспользоваться его преимуществами по полной, каждый компонент вашего приложения должен работать в своем собственном контейнере. Если у вас сложное приложение со множеством компонентов, то вам будет сложно делать так, чтобы все контейнеры запускались и закрывались вместе (не говоря уже о сообщении между ними).

Сообщество Docker придумало популярный инструмент под названием Fig, который позволил использовать один файл YAML для управления всеми контейнерами и конфигурациями Docker. Инструмент стал насколько популярен, что команда Docker наконец решила создать свою собственную версию, основанную на Fig. Они назвали свою новую разработку Docker Compose. Если вкратце, то он упрощает процессы управления Docker-контейнерами (например, запуск, закрытие и настройка связей и объемов внутри контейнеров).

Выполнив все шаги, описанные в данной статье, вы установите Docker и Docker Compose и будете иметь общее представление о принципе работы Docker Compose.

Docker и Docker Compose: Основные элементы

Использование Docker Compose требует объединения нескольких разных элементов Docker в одно. Поэтому перед тем, как начать, давайте рассмотрим основные элементы. Если вы уже знакомы с такими элементами Docker, как хранилище данных (volumes), связи и переадресация порта, то можете сразу переходить к следующему разделу.

Docker-образы

Каждый Docker-контейнер это локальный экземпляр Docker-образа. Docker-образ можно рассматривать как полную установку Linux. Обычно минимальная установка включает установку минимального набора пакетов, необходимых для управления образом. Эти образы используют ядро операционной системы, но поскольку они функционируют внутри Docker-контейнера и видят только свою собственную файловую систему, то вполне можно выполнить распределение, например CentOS на системе Ubuntu (или наоборот).

Большинство Docker-образов распространяются через Docker Hub, поддерживаемый командой Docker. Наиболее популярные общедоступные проекты имеют соответствующий образ, загруженный в Docker Registry, которое вы можете использовать для развертывания программного обеспечения. При возможности, лучше брать «официальные» образы, поскольку команда Docker гарантирует, что они соответствуют передовым стандартам Docker.

Сообщение между Docker-образами

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

Docker предлагает три основных способа решения этой проблемы. Первый и наиболее распространенный – сделать так, чтобы Docker указал переменные среды, которые будут заданы внутри Docker-контейнера. Код, выполняемый внутри Docker-контейнера , затем при запуске проверит значения этих переменных среды и использует их для собственной конфигурации.

Еще один распространенный способ – объем данных Docker. Docker-хранилище данных бывают внутренними и общими. Docker-контейнеры по умолчанию работают таким образом, что каждый раз при закрытии или запуске контейнера он не сохраняет свои данные. Он возвращается в состояние, в котором он находился в момент запуска. Это хорошо для тестирования и разработки, потому что вы гарантированно будете работать с одной и той же средой. Но это плохо в той ситуации, если вы надеетесь, что посты вашего блога, которые вы напечатали в своем WordPress, сохранятся до следующей загрузки Docker.

Если вы задаете внутреннее хранилище, то в папке, которую вы указали для определенного контейнера Docker, данные между запусками будут сохраняться. Например, если вы хотите убедиться, что файлы вашего журнала сохраняются между запусками, вы можете задать внутреннее хранилище /var/log.

Общее хранилище отображает папку внутри Docker-контейнера на папке на хост-компьютере. Это позволяет легко передавать файлы между Docker-контейнером и хост-компьютером, о чем мы поговорим в статье о хранилище данных Docker.

Третий способ связи с Docker-контейнером — через сеть. В Docker сообщение между разными Docker –контейнерами осуществляется через links (связи). Также через links осуществляется переадресация портов, что позволяет вам переадресовывать порты из Docker-контейнера в порты на хост-сервере. Например, вы можете создать связь, которая позволит вашим Docker-контейнерам WordPress и MariaDB переговариваться друг с другом, а переадресации портов – предоставить WordPress для внешнего пользования, чтобы пользователи могли подключиться к нему.

Необходимые условия

Для выполнения шагов в этой статье вам понадобится следующее:

  • Ubuntu 14.04
  • Обычный (non-root) пользователь с sudo-привилегиями

Шаг 1 — Установка Docker

Для начала установите Docker, если он у вас еще не установлен. Самый быстрый способ установить Docker — загрузить и установить его инсталляционный сценарий (вас попросят ввести пароль sudo).

wget -qO- https://get.docker.com/ | sh

Эта команда загружает и выполняет небольшой инсталляционный сценарий, написанный командой Docker. Если вы не доверяете сторонним сценариям или хотите получить более подробную информацию о том, что делает сценарий, ознакомьтесь с уроком об установке и использовании Docker от DigitalOcean или с установочной документацией от Docker.

Работать с Docker будет непросто, если ваш пользователь не конфигурирован должным образом, поэтому добавьте своего пользователя в группу docker посредством следующей команды.

sudo usermod -aG docker $(whoami)

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

Шаг 2 — Установка Docker Compose

Теперь, когда Docker установлен, давайте установим Docker Compose. Обязательным условием является установка python-pip:

sudo apt-get -y install python-pip

Затем устанавливаем Docker Compose:

sudo pip install docker-compose

Шаг 3 — Управление контейнером при помощи Docker Compose

Docker Hub (общедоступный реестр Docker ) содержит простой образ Hello World . Теперь, когда у нас установлен Docker Compose, давайте протестируем его на этом очень простом примере.

Для начала создайте каталог для вашего файла YAML:

mkdir hello-world

Затем внесите изменения в каталог:

cd hello-world

Теперь при помощи своего любимого текстового редактора (здесь мы будем использовать nano) создайте файл YAML:

nano docker-compose.yml

Разместите в файле следующий контент, сохраните файл и выйдите и текстового редактора:

my-test:
  image: hello-world

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

Не выходя из каталога ~/hello-world, выполните следующую команду, чтобы создать контейнер:

docker-compose up

Результат должен начинаться следующим образом:

Output of docker-compose up
Creating helloworld_my-test_1...
Attaching to helloworld_my-test_1
my-test_1 |
my-test_1 | Hello from Docker.
my-test_1 | This message shows that your installation appears to be working correctly.
my-test_1 | 

Затем результат объясняет, что делает Docker:

  1. Docker-клиент связался с Docker-демоном.
  2. Docker-демон извлек изображение «hello-world» из Docker Hub.
  3. Из этого изображения Docker-демон создал новый контейнер, который выполняет исполняемый файл, в результате чего создается результат, который вы сейчас читаете
  4. Docker-демон направил этот результат Docker-клиенту, который отправил его на ваш терминал.

Если процесс не закрывается самостоятельно, нажмите CTRL-C.

Этот простой тест не демонстрирует одно из главных преимуществ Docker Compose — способность запускать и закрывать всю группу Docker-контейнеров одновременно.

Шаг 4 — Знакомство с командами Docker Compose

Давайте познакомимся с командами, поддерживаемыми инструментом docker-compose. Команда docker-compose основывается на принципе «один каталог на каждый контейнер». Вы можете иметь несколько групп Docker-контейнеров, работающих на одном компьютере, — просто создайте один каталог для каждого контейнера и один файл docker-compose.yml для каждого контейнера внутри его каталога.

Пока мы самостоятельно выполняли docker-compose up и использовали CTRL-C. для закрытия. При этом сообщения отладки отображались в окне терминала. Однако это не очень удобно, если при производстве вы захотите, чтобы docker-compose выступал больше как служба. Простой способ добиться этого – просто добавить опцию -d:

docker-compose up -d

docker-compose теперь ответвится в фоновый режим

Чтобы показать свою группу Docker-контейнеров (и остановленных, и работающих), используйте следующую команду:

docker-compose ps

Например, это указывает на то, что контейнер helloworld_my-test_1 остановлен:

Output of `docker-compose ps`
        Name           Command   State    Ports
-----------------------------------------------
helloworld_my-test_1   /hello    Exit 0
Работающий контейнер демонстрирует состояние Up:
Output of `docker-compose ps`
     Name              Command          State        Ports
---------------------------------------------------------------
nginx_nginx_1   nginx -g daemon off;   Up      443/tcp, 80/tcp 

Чтобы остановить все работающие Docker-контейнеры группы приложения, выполните следующую команду в том же каталоге, который файл docker-compose.yml, использовал для запуска Docker-группы:

docker-compose stop

Примечание: команда docker-compose kill также возможна, если вам нужно закрыть контейнеры принудительно.

В некоторых случаях Docker-контейнеры хранят старую информацию во внутреннем хранилище. Если вы хотите начать с чистого листа, вы можете использовать команду rm для полного удаления всех контейнеров в вашей группе контейнеров:

docker-compose rm 

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

Output from wrong directory
        Can't find a suitable configuration file in this directory or any parent. Are you in the right directory?
        Supported filenames: docker-compose.yml, docker-compose.yaml, fig.yml, fig.yaml

Шаг 5 — Доступ к файловой системе Docker-контейнера (опционально)

Если вам нужно поработать над приглашением на ввод команды (command prompt) внутри контейнера, вы можете использовать команду docker exec.

Пример Hello World! закрывается после его выполнения, поэтому нам нужно запустить контейнер, который будет продолжать работать, чтобы мы могли при помощи docker exec получить доступ к файловой системе контейнера. Давайте взглянем на образ Nginx из Docker Hub.

Создайте новый каталог и внесите в него изменение:

mkdir ~/nginx && cd $_

Создайте файл docker-compose.yml в новом каталоге:

nano docker-compose.yml

и вставьте следующее:

nginx:
  image: nginx

Сохраните файл и выйдите. Нам нужно лишь запустить контейнер Nginx в качестве фонового процесса при помощи следующей команды:

docker-compose up -d

Образ Nginx будет загружен, и контейнер будет запущен в фоновом режиме. Теперь для контейнера нам нужен CONTAINER ID. Список всех работающих контейнеров:

docker ps

Вы увидите примерно следующее:

Output of `docker ps`
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
e90e12f70418        nginx               "nginx -g 'daemon off"   6 minutes ago       Up 5 minutes        80/tcp, 443/tcp     nginx_nginx_1

Примечание: При помощи команды docker ps отображается список только работающих контейнеров.

Если бы мы хотели внести изменения в файловую систему внутри этого контейнера, мы бы взяли его ID (в данном случае — e90e12f70418) и при помощи docker exec запустили бы оболочку внутри контейнера:

docker exec -it e90e12f70418 /bin/bash

Опция -t открывает терминал, а опция -i делает его интерактивным. Опция /bin/bash открывает bash-оболочку (bash- shell) к работающему контейнеру. Обязательно используйте ID контейнера. Вы увидите подобное bash-приглашение (bash-prompt) для контейнера:

root@e90e12f70418:/#

Теперь вы можете работать из приглашения на ввод команды. Однако имейте в виду, что если вы не в каталоге, сохраненном как часть хранилища данных, ваши изменения исчезнут при перезапуске контейнера. И еще одно предостережение: большинство Docker – образов создаются при минимальном объеме установки Linux, поэтому некоторые функции и инструменты командной строки, в которым вы привыкли, могут отсутствовать.

Заключение

Итак, мы рассмотрели основные элементы Docker Compose и то, как его установить и запустить. Полный перечень параметров конфигурации для файла docker-compose.yml вы найдете в справочном файле Compose.