Руководство по Docker Compose для начинающих

Содержание:

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

Возможности Docker Compose

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

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

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

Практика применения

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

Допустим, по мере развития проекта становится понятно, что мощностей текущего сервера уже недостаточно. Принимается решение перенести сайты на новый сервер. Без Docker Compose придется переносить и настраивать все сервисы заново. Тогда сама работа займет много времени. Кто же возникает вероятность что-нибудь забыть в процессе.

При помощи Docker Compose можно выполнить перенос сайтов при помощи всего нескольких команд. Потребуется лишь изменить некоторые настройки и перенести на другой сервер резервную копию баз данных.

Создание клиент-серверного приложения

Для примера приведен небольшой сайт (сервер) на Python, умеющий отображать файл с текстом. Запрос на него делает программа-клиент, тоже на Python. Когда файл с сервера будет получен, программа выведет текст из файла на экран.

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

Примечание. Этот проект создавался и тестировался на дистрибутивах Ubuntu и CentOS 7. Для выполнения всех приведенных ниже команд используется стандартный терминал Linux.

Разработка проекта

Создание основного каталога

Сборка тестируемого клиент-серверного приложения начинается с создания каталога проекта (в примере — «project»).

Компоненты каталога
  • Файл docker-compose.yml. В нем сохраняются инструкции, которые используются для запуска и дальнейшей настройки сервисов.
  • Каталог server. Здесь будут храниться файлы, отвечающие за функционирование сервера.
  • Каталог client. В нем расположены файлы для клиент-приложения.

Содержимое основного каталога проекта будет отображаться в следующем виде:

содержимое основного каталога

Работа с папкой server

Подготовка файлов сервера

Следует открыть каталог «server», чтобы создать в нем следующие файлы:

  • Файл server.py. Предназначен для хранения программного кода сервера.
  • Файл index.html. Здесь сохранен текст, который должно выводить при запросе клиент-приложение.
  • Файл Dockerfile. Непосредственно файл контейнера, который содержит директивы для создания серверного окружения.

После создания трех упомянутых выше файлов, содержимое каталога «server» должно выглядеть так:

содержимое каталога «server

Работа с файлом server.py

Теперь нужно открыть файл «server.py» предпочитаемым текстовым редактором, чтобы добавить в него следующий код:

#!/usr/bin/env python3
# Импорт системных библиотек Python.
# Эти библиотеки будут использоваться для создания веб-сервера.
# Не нужно устанавливать что-то особенное, эти библиотеки устанавливаются вместе с Python.
import http.server
import socketserver

# Эта переменная нужна для обработки запросов клиента к серверу.
handler = http.server.SimpleHTTPRequestHandler
# Здесь указываемся, что сервер будет запущен на порте 1234.
# Нужно запомнить эти сведения, так как они очень пригодятся в дальнейшем, при работе с docker-compose.
with socketserver.TCPServer(("", 1234), handler) as httpd:
# Благодаря этой команде сервер будет выполняться постоянно, ожидая запросов от клиента.
  httpd.serve_forever()

Важно! При добавлении информации нужно обязательно сохранять форматирование, как дано в примере.

Работа с файлом index.html

Далее потребуется отредактировать index.html, добавив в него такое содержимое:

Docker-Compose is magic!

Работа с Dockerfile

Теперь следует произвести настройку файла Dockerfile. С помощью него будет организована среда выполнения для Python-сервера. В примере основой создаваемого контейнера будет официальный образ для запуска Python-приложений.

Ниже приведено содержимое файла:

# На всякий случай – Dockerfile всегда должен начинаться с импорта базового образа.
# Для этого используется ключевое слово 'FROM'.
# Здесь следует импортировать образ python (с DockerHub).
# В результате, в качестве имени образа, нужно указать 'python', а в качестве версии - 'latest'.

FROM python:latest

# Для того чтобы запустить в контейнере код, написанный на Python, нужно импортировать файлы 'server.py' и 'index.html'. Для этого используется ключевое слово 'ADD'.
# Первый параметр, 'server.py', представляет собой имя файла, хранящегося на компьютере.
# Второй параметр — '/server/' — это путь, по которому нужно разместить указанный файл в образе.
# помещаем файл в папку образа '/server/'.

ADD server.py /server/
ADD index.html /server/

# Воспользуемся командой 'WORKDIR'.
# Она позволяет изменить рабочую директорию образа.
# В качестве директории, в которой будут выполняться все команды, нужно установить '/server/'.

WORKDIR /server/

Важно! При добавлении информации нужно обязательно сохранять форматирование, как дано в примере.

Создание клиент-приложения

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

Файлы клиента

Сначала следует открыть каталог «client» и создать в нем файлы:

  • Файл client.py. Предназначен для хранения выполняемого кода клиента.
  • Файл Dockerfile. Используется так же, как и одноименный файл в папке server. В нем сохранена инструкция по созданию среды запуска кода на стороне клиента.

После этих операций в каталоге client должны храниться следующие файлы:

содержимое каталога client

Работа с файлом Python

Снова следует открыть текстовый редактор, чтобы добавить в client.py такой код:

#!/usr/bin/env python3
# Импортируется системная библиотека Python.
# Она используется для загрузки файла 'index.html' с сервера.
# Специально ничего устанавливать не нужно, эта библиотека устанавливается вместе с Python.

import urllib.request

# Эта переменная содержит запрос к 'http://localhost:1234/'.
# localhost указывает на то, что программа работает с локальным сервером.
# 1234 - номер порта, который предлагается запомнить при настройке серверного кода.

fp = urllib.request.urlopen("http://localhost:1234/")

# 'encodedContent' соответствует закодированному ответу сервера ('index.html').
# 'decodedContent' соответствует раскодированному ответу сервера (тут будет то, что нужно вывести на экран).

encodedContent = fp.read()
decodedContent = encodedContent.decode("utf8")

# Выводим содержимое файла, полученного с сервера ('index.html').

print(decodedContent)

# Закрываем соединение с сервером.

fp.close()

Важно! При добавлении информации нужно обязательно сохранять форматирование, как дано в примере.

Работа с файлом Dockerfile

Аналогично серверу, для клиент-приложения будет создан небольшой Dockerfile. Он будет формировать среду для работы клиента.

Ниже представлен его код:

# То же самое, что и в серверном Dockerfile.

FROM python:latest

# Импортируем 'client.py' в папку '/client/'.

ADD client.py /client/

# Устанавливаем в качестве рабочей директории '/client/'.

WORKDIR /client/

Важно! При добавлении информации нужно обязательно сохранять форматирование, как дано в примере.

Работа с Docker Compose

На предыдущих этапах было создано два проекта – серверное и клиент-приложение. Оба они обладают своим файлом Dockerfile. До этого момента применялись только основной функционал Docker. Далее к работе будет подключен Docker Compose — потребуется отредактировать docker-compose.yml, созданный ранее.

В этом примере не стоит задача ознакомиться со всеми возможными командами, доступными для использования в docker-compose.yml. Основная цель – увидеть, как Docker Compose можно применить на практике.

Пример файла docker-compose.yml

Важно! При добавлении информации в файл docker-compose.yml нужно обязательно сохранять форматирование, данное в примере. Это прежде всего касается отступов перед блоками. Если это расстояние нарушить, будет выведена ошибка.

# Файл docker-compose должен начинаться с тега версии.
# Мы используем "3" так как это - самая свежая версия на момент написания этого кода.

version: "3"

# Следует учитывать, что docker-composes работает с сервисами. 1 сервис = 1 контейнер.
# Сервисом может быть клиент, сервер, сервер баз данных...
# Раздел, в котором будут описаны сервисы, начинается с 'services'.

services:

  # Будут созданы клиентское и серверное приложения.
  # Это означает, что нам нужно два сервиса.
  # Первый сервис (контейнер): сервер. Назвать его можно так, как нужно разработчику.
  # Понятное название сервиса помогает определить его роль.
  # Здесь мы, для именования соответствующего сервиса, используем ключевое слово 'server'.

  server:
 
    # Ключевое слово "build" позволяет задать
    # путь к файлу Dockerfile, который нужно использовать для создания образа,
    # который позволит запустить сервис.
    # Здесь 'server/' соответствует пути к папке сервера,
    # которая содержит соответствующий Dockerfile.

    build: server/

    # Команда, которую нужно запустить после создания образа.
    # Следующая команда означает запуск "python ./server.py".

    command: python ./server.py

    # Вспомните о том, что в качестве порта в 'server/server.py' указан порт 1234.
    # Если нужно обратиться к серверу со своего компьютера (находясь за пределами контейнера),
    # следует организовать перенаправление этого порта на порт компьютера.
    # Сделать это поможет ключевое слово 'ports'.
    # При его использовании применяется следующая конструкция: [порт компьютера]:[порт контейнера]
    # В данном случае нужно использовать порт компьютера 1234 и организовать его связь с портом
    # 1234 контейнера (так как именно на этот порт сервер ожидает поступления запросов).

    ports:
      - 1234:1234

  # Второй сервис (контейнер): клиент.
  # Этот сервис назван 'client'.

  client:
    # Здесь 'client/ соответствует пути к папке, которая содержит
    # файл Dockerfile для клиентской части системы.

    build: client/

    # Команда, которую нужно запустить после создания образа.
    # Следующая команда означает запуск "python ./client.py".
 
    command: python ./client.py

    # Ключевое слово 'network_mode' используется для описания типа сети.
    # Тут указывается, что контейнер может обращаться к 'localhost' компьютера.

    network_mode: host

    # Ключевое слово 'depends_on' позволяет указывать, должен ли сервис,
    # прежде чем запуститься, ждать, когда будут готовы к работе другие сервисы.
    # Нужно, чтобы сервис 'client' дождался бы готовности к работе сервиса 'server'.
 
    depends_on:
      - server

Создание готового образа

Когда docker-compose.yml получит требуемые для работы команды, останется выполнить сборку проекта. Она делается почти аналогично docker build.

Представленная ниже команда позволяет одновременно работать с двумя и более приложениями:

$ docker-compose build

Если все сделано правильно, в терминале будет отображен следующий результат:

команда docker-compose build

Тестирование проекта

Сборка проекта завершена и можно переходить к тестированию проекта. Для этого следует выполнить команду:

$ docker-compose up

Она по сути соответствует команде docker run, используемой в Docker при работе с одним контейнером.

команда docker-compose up

В окне терминала можно увидеть строку «Docker-Compose is magic!». Так клиентская программа сигнализирует, что выполнила запрос на вывод содержимого файла «index.html» серверной программе, после чего вторая передала информацию клиенту. Это значит, что проект успешно запущен и работает.

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

Docker-Compose is magic!

Дополнительная информация

Ниже приведены несколько часто используемых полезных команд Docker Compose.

  • Команда предназначена для остановки и удаления контейнеров, которые были созданы с помощью «docker-compose up»:
$ docker-compose down
  • Ознакомиться с журналами сервисов можно выполнив команду:
$ docker-compose logs -f [service name]
  • Посмотреть список используемых сервисов можно командой (на примере данного проекта):
$ docker-compose ps

команда docker-compose ps

  • Чтобы запустить команду в работающем контейнере используется следующий синтаксис:
$ docker-compose exec [service name] [command]
  • Увидеть в терминале список образов можно, введя команду:
$ docker-compose images