Различные примеры проектов с использованием Docker Compose можно посмотреть по ссылке https://github.com/docker/awesome-compose
Общая структура файла docker-compose.yml выглядит следующим образом:
services:
service_1:
…
service_2:
…
Ранее все версии docker-compose.yml начинались с тега version:, который на данный момент считается устаревшим и необязательным.
В разделе serviсes: описываются сервисы, которые необходимо собрать. Данный тег является обязательным.
Далее указывается тег с названием сервиса. В примере он назван service_1:, но может быть любым, например server, db, web, chtougodno.
Следом идет container_name:, в котором указывается название создаваемого контейнера. Тег не обязательный, но его желательно прописывать для своего же удобства.
Далее идет один из двух тегов:
build: применяется в случае сборки образа из Dockerfile
build: server/ , где server/ — путь до Dockerfile относительно docker-compose.yml. Путь должен быть каталогом.
build:
context: frontend
target: development
Возможны и другие варианты. Подробнее в официальной документации.
image: применяется в случае скачивания образа из репозитория
image: elasticsearch:7.16.1, где elasticsearch — название образа, а 7.16.1 — его версия
Следом описываются возможные варианты тегов
ports: Для обращения компьютера к контейнеру необходимо указать порты для связи в формате [порт компьютера]:[порт контейнера]
ports:
— 1234:1234
restart: Указывает политику перезапуска. Поддерживает следующие значения
‘no’ — не пытаться перезапустить контейнер, если он остановился или сломался. ОБЯЗАТЕЛЬНО указывается с кавычками, иначе no будет интерпретирован как false.
always — всегда перезапускать, если контейнер остановился. НЕ РАБОТАЕТ, если остановить вручную командой docker stop.
on-failure — перезапустить в случае остановки по коду ошибки. Если контейнер отработал с кодом 0 (ноль), то он остановится и не запустится.
unless-stopped — перезапускается до тех пор, пока не будет принудительно остановлен.
healthcheck: — проверка работоспособности того, что находится внутри контейнера. Имеет 5 свойств:
test: [«CMD», «http://localhost:1234»] — определяет КОМАНДУ, которая будет проводить проверку работоспособности, а так же ЧТО нужно ПРОВЕРИТЬ.
interval: 10s — время перед запуском хелсчека, а также интервал запуска дальнейших проверок.
timeout: 5s — время, которое Docker ждет, когда программа вернет код завершения, прежде чем объявить о ее сбое.
retries: 5 — количество последовательных ошибок, после которых контейнеру дается статус unhealthy
start_period: 10s — количество секунд, которое загружается контейнер. В течение этого времени, если поверка работоспособности возвращает код отличный от 0, контейнер не помечается как unhealthy.
Другие примеры составления healthcheck.
environment: — Переменные окружения.Для каждого сервиса они свои. Примеры тут.
Синтаксис может быть как
— MYSQL_DATABASE=example
так и
MYSQL_DATABASE: example
Примерный (но не полный) порядок приоритета переменных окружения:
- Устанавливаются в командной строке перед применением docker compose
- Переменные самого файла docker-compose.yml
- Переменные из файла .env
Удобную таблицу с примерами порядка приоритета можно посмотреть в официальной документации.
secrets:
Секрет для передачи каких-либо данных конфигурируется в трех местах:
- в «корне» файла спецификации
- в настройках непосредственно сервиса
- в настройках environment
Вот пример
secrets: # !!! 1 !!! делаем запись в конфигурации о том, что в файле будет "секрет"
db_password: # тут пишем название секрета
file: db_password.txt # сюда записываем путь фо файла с секретом относительно docker-compose.yml
db_root_password:
file: db_root_password.txt
environment: #
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password # !!! 3 !!! прописываем пути, откуда будут браться секреты
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD_FILE: /run/secrets/db_password # !!! 3 !!! прописываем пути, откуда будут браться секреты
secrets: # !!! 2 !!! определяем, какие секреты будут в конкретном сервисе
- db_root_password
- db_password
volumes:
Volumes (тома) можно назвать пробросом папок. Конфигурируются двумя способами :
- в описании сервиса
- в корне и в описании сервиса
Пример использования в одном сервисе (первый случай)
volumes:
- /path/your/data/where/is/the/script/:/data/
Где /path/your/data/where/is/the/script/ путь до папки или скрипта на локальной машине, а /data/ — куда нужно все положить. Проще говоря, это аналог команды cp.
Пример использования и в корне, и в описании сервиса
services:
backend:
image: example/database
volumes:
- db-data:/etc/data # тут мы просто говорим, что из тома нужно скопировать данные в /etc/data
backup:
image: backup-service
volumes:
- db-data:/var/lib/backup/data
volumes:
db-data: # это том, который мы создали на локальной машине с помощью команды docker volume create database и в который положили какие-то данные
Еще больше про тома можно почитать в документации тут и тут.
networks:
По умолчанию Compose настраивает единую сеть для вашего приложения. Каждый контейнер для службы подключается к сети по умолчанию и доступен как для других контейнеров в этой сети, так и для обнаружения по имени службы.
В основном тег верхнего уровня networks: прописывают в двух случаях:
- необходимо поменять имя сети или сделать кастомные настройки
- необходимо сделать несколько сетей для изоляции сервисов друг от друга
Пример первого случая
networks:
db-data: #даем имя новой сети (сеть default у нас по прежнему существует)
driver: bridge #указываем дополнительные настройки сети, например назначаем драйвер
После этого в настройках сервиса необходимо явно прописать причастность будущего контейнера к этой сети
db: #имя сервиса для примера
image: postgres #имедж для примера
networks:
- db-data # так записывается настройка сети
Пример второго случая
services:
db: #сервис 1
networks:
- backnet
backend: #сервис 2
networks:
- backnet
- frontnet
proxy: #сервис 3
networks:
-frontnet
networks: #описание сетей
backnet: # название первой сети
frontnet: # название второй сети
Таким образом, сервис 1 и 3 изолированы друг от друга и общаются между собой через сервис 2.
Другие случаи как всегда наглядно и со множеством примеров в официальной документации.
sysctls:
С данным тегом используются команды sysctl для внесения изменений в параметры ядра.
command:
Команда, которая будет запущена при загрузке контейнера
lables:
Используется для записи метаданных в контейнер
expose:
EXPOSE Используется исключительно для определения порта, на котором запущено приложение внутри контейнера docker.
С помощью «expose» вы определяете связь внутри сети. Если вы хотите предоставить доступ к портам по умолчанию, вам не нужно определять «expose» в вашем файле docker-compose.
depends_on:
С помощью атрибута depends_on вы можете управлять порядком запуска и завершения работы служб. Это полезно, если службы тесно связаны и последовательность запуска влияет на функциональность приложения.
Есть краткий синтаксис и длинный. В кратком по умолчанию сервис отмечается как «запущен»
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
В примере сервис web стартанет после поднятия redis и db.
При использовании длинного синтаксиса возможны варианты.
condition: Устанавливает условие, при котором зависимость считается удовлетвореннойservice_started: Эквивалент краткого синтаксиса, описанного вышеservice_healthy: Указывает, что ожидается, что зависимость будет «работоспособной» перед запуском зависимой службы.service_completed_successfully: Указывает, что ожидается успешное завершение работы зависимости перед запуском зависимой службы.
services:
web:
build: .
depends_on:
db:
condition: service_healthy
restart: true
redis:
condition: service_started
redis:
image: redis
db:
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
retries: 5
start_period: 30s
timeout: 10s