В предыдущих уроках мы познакомились с основами Docker, научились работать с образами, контейнерами, томами и сетями. Теперь пришло время познакомиться с Docker Compose — инструментом, который упрощает работу с многоконтейнерными приложениями и позволяет эффективно управлять их конфигурацией и жизненным циклом. В этом уроке мы также подробно рассмотрим язык разметки YAML, который используется для написания файлов конфигурации Docker Compose.
В данную статью добавлены ссылки на github в примере файла docker_compose.yml, т.к. Дзен не умеет сохранять корректную табуляцию. Так же общая ссылка на github для данного урока:
Что такое Docker Compose?
Docker Compose — это инструмент, который позволяет определять и запускать многоконтейнерные приложения с помощью файла YAML. С Docker Compose вы можете описать конфигурацию всех ваших сервисов в одном файле docker-compose.yml, а затем запустить их одной командой. Это особенно полезно при разработке и тестировании приложений, состоящих из нескольких компонентов, таких как веб-сервер, база данных, кеш, очередь сообщений и другие.
Установка Docker Compose.
Docker Compose теперь интегрирован в сам Docker на Linux, начиная с версии Docker Engine 20.10. Вам не нужно устанавливать его отдельно — достаточно иметь актуальную версию Docker. Тем не менее на канале есть статья как установить его отдельно (если очень хочется 😉):
Основы языка YAML.
YAML (YAML Ain't Markup Language) — это читаемый человеком формат сериализации данных, используемый для хранения и передачи структурированных данных. В Docker Compose файлы конфигурации пишутся на языке YAML, поэтому важно понимать его синтаксис и особенности.
Основные элементы YAML:
- Ключ-значение: Определение пар ключей и значений.
ключ: значение
- Отступы: Структура данных определяется отступами (пробелами). Используйте два пробела для каждого уровня вложенности. Табуляции не рекомендуются.
сервис1:
ключ: значение
- Списки: Перечисление элементов.
- элемент1
- элемент2
- Словари: Коллекция пар ключ-значение.
ключ1: значение1
ключ2: значение2
- Комментарии: Начинаются с символа #.
# Это комментарий
- Якоря и ссылки: Позволяют переиспользовать блоки конфигурации.
общая_конфигурация: &default
образ: nginx
сервис1:
<<: *default
Создание приложения с Docker Compose и YAML.
Рассмотрим пример приложения, состоящего из веб-сервера на Python Flask, базы данных MongoDB и инструмента мониторинга Prometheus.
Шаг 1: Структура проекта
Создайте директорию для вашего проекта и перейдите в неё:
mkdir myapp
cd myapp
Шаг 2: Создайте файл docker-compose.yml.
Давайте подробно разберём содержимое файла docker-compose.yml:
# Определение сервисов приложения
services:
web:
build: ./web # Указание на директорию с Dockerfile для сборки образа
ports:
- '5000:5000' # Переадресация порта 5000 хоста на порт 5000 контейнера
depends_on:
- db # Зависимость от сервиса db
networks:
- app-network # Подключение к сети app-network
db:
image: mongo:4.4 # Используемый образ MongoDB версии 4.4
volumes:
- db-data:/data/db # Подключение тома db-data к директории /data/db в контейнере
networks:
- app-network
prometheus:
image: prom/prometheus # Используемый образ Prometheus
ports:
- '9090:9090' # Переадресация порта 9090
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml #
Подключение файла конфигурации
networks:
- app-network
# Определение томов для хранения данных
volumes:
db-data: # Том для данных MongoDB
# Определение пользовательской сети
networks:
app-network:
Разбор YAML-синтаксиса:
- services: Ключ верхнего уровня, содержащий описание всех сервисов.
- web, db, prometheus: Имена сервисов.
- Отступы: Каждый уровень вложенности определяется отступами в два пробела.
- Списки: Используются для перечисления значений, например, список портов или сетей.
Шаг 3: Подготовьте файлы проекта.
Создайте директорию для веб-приложения:
mkdir web
Создайте файл web/app.py с содержимым:
from flask import Flask
from pymongo import MongoClient
app = Flask(__name__)
client = MongoClient('db', 27017) # Подключение к сервису db по имени
db = client['mydatabase']
collection = db['visits']
@app.route('/') def hello():
collection.insert_one({'message': 'Hello from Docker Compose!'})
count = collection.count_documents({})
return f'Hello from Docker Compose! This page has been visited {count} times.'
if __name__ == '__main__':
app.run(host='0.0.0.0')
Создайте файл web/requirements.txt:
*Данный пример является не очень хорошим, т.к. в файле requirements.txt должны быть отражены версии.
flask
pymongo
Создайте файл web/Dockerfile (о dockerfile я расскажу в след. уроке, пока просто скопируйте содержимое и не задумывайтесь):
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Создайте директорию и файл для конфигурации Prometheus:
mkdir -p prometheus
Создайте файл prometheus/prometheus.yml:
global:
scrape_interval: 15s # Интервал опроса метрик
scrape_configs:
- job_name: 'docker'
static_configs:
- targets: ['web:5000'] # Цель для сбора метрик — сервис web на порту 5000
Шаг 4: Запустите приложение.
Выполните команду:
docker compose up -d
Docker Compose построит образ для веб-приложения, скачает необходимые образы, создаст и запустит контейнеры.
Шаг 5: Проверьте работу приложения.
Откройте браузер и перейдите по адресу http://localhost:5000. Вы должны увидеть сообщение о количестве посещений.
Откройте Prometheus по адресу http://localhost:9090, чтобы убедиться, что сервис мониторинга работает.
Глубокий разбор YAML в контексте Docker Compose.
1. Отступы и структура.
YAML использует отступы для определения вложенности. Важно использовать пробелы, а не табуляции.
Пример:
services:
web:
build: ./web
ports: - '5000:5000'
Здесь web вложен в services, а build и ports вложены в web.
2. Списки.
Списки создаются с помощью дефиса - и отступа.
Пример:
ports:
- '5000:5000'
- '8080:80'
3. Словари.
Словари — это пары ключ-значение.
Пример:
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: secret
4. Ссылки и якоря.
YAML позволяет создавать ссылки на повторяющиеся блоки конфигурации с помощью якорей & и ссылок *.
Пример:
default-env: &default-env
FLASK_ENV: development
DEBUG: 'true'
services:
web:
environment:
<<: *default-env
CUSTOM_VAR: value
Здесь мы определили якорь &default-env и использовали его в environment сервиса web с помощью ссылки *default-env.
5. Комментарии.
Комментарии начинаются с # и игнорируются парсером.
Пример:
# Это комментарий
services:
web: # Параметры веб-сервера
build: ./web
Домашнее задание.
Задание 1: Создание собственного файла docker-compose.yml.
- Создайте новый проект с сервисами по вашему выбору.
- Используйте YAML-синтаксис для описания сервисов, томов и сетей.
- Включите использование переменных окружения и якорей для оптимизации файла.
Задание 2: Использование якорей и ссылок.
- В файле docker-compose.yml создайте общую конфигурацию для сервисов (например, переменные окружения или параметры сети).
- Используйте якоря & и ссылки *, чтобы переиспользовать конфигурацию в нескольких сервисах.
Задание 3*: Изучение расширенных возможностей YAML.
- Исследуйте дополнительные возможности YAML, такие как вложенные списки и словари, типы данных (числа, строки, булевы значения).
- Попробуйте использовать эти возможности в вашем docker-compose.yml.
Что дальше?
В следующем уроке мы подробно рассмотрим работу с Dockerfile. Вы узнаете, как создавать собственные образы, оптимизировать их размер, использовать кэширование слоёв и применять лучшие практики при написании Dockerfile. Это позволит вам создавать более эффективные, безопасные и производительные контейнеры для ваших приложений.