Продвинутое конфигурирование Docker Compose (перевод)

в 16:02, , рубрики: devops, docker-compose, Блог компании Отус, виртуализация, Серверное администрирование

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

Продвинутое конфигурирование Docker Compose (перевод) - 1

Контроль порядка запуска

Docker Compose запускает контейнеры в порядке зависимостей, используя опцию depends_on, чтобы указывать, когда запускается сервис. Для определения порядка запуска Compose применяет depends_on, links, volumes_from и network_mode: «service: ...».

Если контейнер должен дождаться состояния “ready” другого контейнера, можно использовать инструменты wait-for-it или dockerize. Они будут проверять хосты и порты до тех пор, пока TCP соединение не будет подтверждено. Для включения принудительного ожидания в композицию необходимо добавить entrypoint:

version: '2'

services:
    web:
        build: .
        ports:
            - "80:8000"
        depends_on:
            - db
        entrypoint: "./wait-for-it.sh db:5432"
    db:
        image: postgres

Вы всегда можете самостоятельно написать скрипт-обёртку, если возникнет необходимость в усилении контроля.

Запуск нескольких копий Compose проекта

Если вам понадобится несколько копий окружений с одинаковой композицией (или docker-compose.yml файлом), просто запустите docker-compose up -p new_project_name.

Переменные среды

Переменные среды оболочки могут быть использованы для установки значений в композициях:
Установить переменные среды:

$ TAG="latest"
$ echo $TAG
latest
$ DB="postgres"
$ echo $DB
postgres

Использовать переменную среды в Docker Compose файле:

db:
    image: "${DB}:$TAG"

Docker Compose принимает и ${DB}, и $TAG. Также можно задать переменные среды в контейнерах:

web:
    environment:
        - PRODUCTION=1

Можно даже передать переменные среды внутрь контейнеров:

$ PRODUCTION=1
$ echo $PRODUCTION
1

Файл окружения

Для гарантии передачи переменной среды, необходимо хранить её в файле среды. Назовите файл .env и сохраните в рабочей директории. Docker Compose игнорирует пустые строки (используйте их для лучшей читаемости) и код, начинающийся с # (то есть комментарии). Вы можете присвоить переменные для дальнейшей подстановки, а также задать переменные Compose CLI:

COMPOSE_API_VERSION
COMPOSE_FILE
COMPOSE_HTTP_TIMEOUT
COMPOSE_PROJECT_NAME
DOCKER_CERT_PATH
DOCKER_HOST
DOCKER_TLS_VERIFY

Пример файла среды:

# ./.env 
# для нашей промежуточной среды

COMPOSE_API_VERSION=2
COMPOSE_HTTP_TIMEOUT=45
DOCKER_CERT_PATH=/mycerts/docker.crt
EXTERNAL_PORT=5000

Использование нескольких файлов Docker Compose

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

Docker Compose по умолчанию читает два файла: docker-compose.yml и docker-compose.override.yml. В файле docker-compose-override.yml можно хранить переопределения для существующих сервисов или определять новые. Чтобы использовать несколько файлов (или файл переопределения с другим именем), необходимо передать -f в docker-compose up (порядок имеет значение):

$ docker-compose up -f my-override-1.yml my-overide-2.yml

Когда две опции конфигурации совпадают, новое значение заменяет или расширяет первоначальное.

В этом примере новое значение переписывает старое и command запускает my_new_app.py:

# оригинальный сервис
command: python my_app.py

# новый сервис
command: python my_new_app.py
При использовании опции с несколькими значениями (ports, expose, external_links, dns, dns_search и tmpfs), Docker Compose объединяет значения (в примере ниже Compose открывает порты 5000 и 8000):

# оригинальный сервис
expose:
    - 5000
    
# новый сервис
expose:
    - 8000

Если используются environment, labels, volumes, или devices, Docker Compose объединяет результаты. В следующем примере три переменные среды становятся FOO=Hello и BAR=«Python Dev!»:

# оригинальный сервис
environment:
    - FOO=Hello
    - BAR=World

# новый сервис
environment:
    - BAR="Python Dev!"

Различные среды
Начнём с базового Docker Compose файла для приложения (docker-compose.yml):
web:
    image: "my_dockpy/my_django_app:latest"
    links:
        - db
        - cache

db:
    image: "postgres:latest"

cache:
    image: "redis:latest"

На сервере разработки мы хотим открыть порты, смонтировать код как том и создать веб-изображение (docker-compose.override.yml):

web:
    build: .
    volumes:
        - ".:/code"
    ports:
        - "8883:80"
    environment:
        DEBUG: "true"

db:
    command: "-d"
    ports:
        - "5432:5432"

cache:
    ports:
        - "6379:6379"

docker-compose up автоматически читает файл переопределения и применяет его. Также понадобится продакшн версия Docker Compose приложения, которую назовём docker-compose.production.yml:

web:
    ports:
        - "80:80"
    environment:
        PRODUCTION: "true"

cache:
    environment:
        TTL: "500"

Когда понадобится развернуть продакшн файл, просто запустим следующее:

$ docker-compose -f docker-compose.yml -f docker-compose.production.yml up -d

Примечание: Docker Compose читает docker-compose.production.yml, но не docker-compose.override.yml.

Задачи администрирования

Необходимо запустить административную копию приложения, чтобы иметь возможность выполнять определённые задачи, например, бэкапить базу данных. Используя уже упомянутый файл docker-compose.yml, создадим файл docker-compose.admin.yml:

dbadmin:
    build: database_admin/
    links:
        - db

А затем, выполним следующую команду:

$ docker-compose -f docker-compose.yml -f docker-compose.admin.yml run dbadmin db-backup

Расширение сервисов

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

Создать common-services.yml (можно назвать его как угодно):

webapp:
    build: .
    ports:
        - "8000:8000"
    volumes:
        - "/data"

Создать базовый docker-compose.yml. Например:

web:
    extends:
        file: common-services.yml
        service: webapp

Кроме этого, определить (или переопределить) конфигурацию и добавить другие сервисы можно локально:

web:
    extends:
        file: common-services.yml
        service: webapp
    environment:
        - DEBUG=1
    cpu_shares: 5
    links:
        - db

important_web:
    extends: web
    cpu_shares: 10

db: 
    image: postgres

Распространённые проблемы

Контроль порядка запуска

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

Файл окружения

Если вы определяете переменные среды в оболочке или через командную строку во время работы docker-compose, эти переменные будут иметь приоритет над .env файлом.

Не стоит хранить переменные среды в системе контроля версии. Если вы используете файл среды, добавьте его в локальный файл игнорирования и создайте образец env.sample, похожий на следующий пример (если предполагается, что используется файл .env, описанный выше):

COMPOSE_API_VERSION=    # должно быть 2
COMPOSE_HTTP_TIMEOUT=   # мы используем 30 на продакшне и 120 в разработке
DOCKER_CERT_PATH=       # храните путь сертификации здесь
EXTERNAL_PORT=          # установите внешний порт здесь (запомните, 5000 для Flask и 8000 для Django)

Использование нескольких файлов Docker Compose

Обратите внимание, Docker Compose объединяет файлы в заданном вами порядке.

Расширение сервисов

Сервисы никогда не делят links, volumes_from или depends_on, используя extends; links и volumes_from всегда должны быть определены локально.

The end

С вопросами, предложениями и замечаниями — welcome в комментарии. А если хочется похоливарить в режиме реального времени — присоединяйтесь к нам на Дне открытых дверей курса.

Автор: Tully

Источник

Поделиться

* - обязательные к заполнению поля