Files
airflow-greenplum/plans/dockerfile-improvements.md
T
ddadmin a6a3559ab9 refactor(csv): удален легаси CSV-пайплайн и связанные с ним файлы
- Зачем:
  - Пример базовой загрузки CSV перенесен в отдельный репозиторий `airflow-manual` для разделения учебных треков.
- Что:
  - удалены DAG-файлы `csv_to_greenplum` и вспомогательные скрипты `helpers/greenplum.py`, `orders_ddl.sql`.
  - из `docker-compose.yml` и `.env.example` удалены переменные и тома (`airflow_data`), необходимые для CSV.
  - очищена документация (`README.md`, `TESTING.md`, `educational-tasks.md`) и тесты (`test_dags_smoke.py`, `conftest.py`).
  - отмечен выполненным 'Этап 1' в `TODO.md`.
- Проверка:
  - `make test` проходит успешно (smoke-тесты оставшихся DAG-ов не затронуты).
2026-03-08 19:13:19 +03:00

17 KiB
Raw Blame History

План улучшения Dockerfile и docker-compose.yml

Обзор

Документ описывает план улучшения Dockerfile для Airflow и его интеграции с docker-compose.yml на основе анализа best practices.

Согласованные изменения

Переименовать DockerfileDockerfile.airflow Обновить build: .build: { context: ., dockerfile: Dockerfile.airflow } Добавить YAML anchors для устранения дублирования конфигурации Добавить healthcheck для airflow-webserver Исправить расположение requirements.txt в Dockerfile Добавить LABEL в Dockerfile Добавить USER airflow после установки зависимостей Добавить проверку pip check Переименовать контейнеры (gp_airflow_webgp_airflow_webserver, gp_airflow_schgp_airflow_scheduler)


Часть 1: Изменения в Dockerfile

Текущее состояние (Dockerfile)

FROM apache/airflow:2.9.2

COPY airflow/requirements.txt /requirements.txt
RUN pip install --no-cache-dir -r /requirements.txt

Новое состояние (Dockerfile.airflow)

# Apache Airflow с дополнительными зависимостями для Greenplum
FROM apache/airflow:2.9.2

LABEL maintainer="your-email@example.com"
LABEL description="Airflow with Greenplum and Pandas dependencies"
LABEL version="1.0"

# Копируем requirements в стандартное расположение
COPY airflow/requirements.txt /opt/airflow/requirements.txt

# Устанавливаем зависимости
RUN pip install --no-cache-dir -r /opt/airflow/requirements.txt \
    && pip check \
    && rm -rf /tmp/pip-*

# Переключаемся на пользователя airflow
USER airflow

WORKDIR /opt/airflow

Обоснование изменений:

  1. LABEL - стандартная практика для документирования образов
  2. /opt/airflow/requirements.txt - стандартное расположение для Airflow
  3. pip check - проверка совместимости установленных пакетов
  4. USER airflow - безопасность и соответствие best practices
  5. WORKDIR /opt/airflow - явное указание рабочей директории

Часть 2: Изменения в docker-compose.yml

Основные изменения:

  1. Добавить YAML anchors для устранения дублирования
  2. Обновить build для всех Airflow сервисов
  3. Добавить healthcheck для airflow-webserver
  4. Добавить комментарии для пояснения сокращений в именах контейнеров

Структура YAML anchors:

x-airflow-common-env: &airflow-env
  TZ: ${TZ:-Europe/Moscow}
  AIRFLOW__CORE__LOAD_EXAMPLES: "False"
  AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://${PG_USER}:${PG_PASSWORD}@pgmeta:5432/${PG_DB}
  AIRFLOW__WEBSERVER__SECRET_KEY: ${AIRFLOW__WEBSERVER__SECRET_KEY}
  AIRFLOW_CONN_GREENPLUM_CONN: postgresql://${GP_USER}:${GP_PASSWORD}@greenplum:${GP_PORT:-5432}/${GP_DB}
  AIRFLOW_CONN_BOOKINGS_DB: postgresql://${BOOKINGS_DB_USER}:${BOOKINGS_DB_PASSWORD}@bookings-db:5432/demo

x-airflow-common-volumes: &airflow-volumes
  - ./airflow/dags:/opt/airflow/dags
  - ./sql:/sql:ro
  - airflow_data:/opt/airflow/data

x-airflow-common-depends: &airflow-depends
  pgmeta:
    condition: service_healthy
  greenplum:
    condition: service_healthy
  airflow-init:
    condition: service_completed_successfully

Изменения для airflow-webserver:

airflow-webserver:
  build:
    context: .
    dockerfile: Dockerfile.airflow
  image: airflow-custom:latest
  container_name: gp_airflow_webserver
  env_file: .env
  environment:
    <<: *airflow-env
  command: airflow webserver
  ports:
    - "8080:8080"
  volumes:
    <<: *airflow-volumes
    # requirements.txt монтируется как volume для удобства разработки
    # При изменении зависимостей не требуется пересборка образа
    - ./airflow/requirements.txt:/opt/airflow/requirements.txt
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
    interval: 30s
    timeout: 10s
    retries: 5
    start_period: 40s
  depends_on:
    <<: *airflow-depends

Изменения для airflow-scheduler:

airflow-scheduler:
  build:
    context: .
    dockerfile: Dockerfile.airflow
  image: airflow-custom:latest
  container_name: gp_airflow_scheduler
  env_file: .env
  environment:
    <<: *airflow-env
  command: airflow scheduler
  volumes:
    <<: *airflow-volumes
    - ./airflow/requirements.txt:/opt/airflow/requirements.txt
  depends_on:
    <<: *airflow-depends

Изменения для airflow-init:

airflow-init:
  build:
    context: .
    dockerfile: Dockerfile.airflow
  image: airflow-custom:latest
  # Имя контейнера закомментировано (одноразовый сервис)
  user: "0"
  env_file: .env
  environment:
    <<: *airflow-env
  volumes:
    <<: *airflow-volumes
  command: >
    bash -lc "
      set -e;
      mkdir -p /opt/airflow/data && chown -R airflow:root /opt/airflow/data;
      for i in {1..30}; do
        su -s /bin/bash airflow -c \"PATH='/home/airflow/.local/bin:$${PATH}' airflow db migrate\" && break || echo 'waiting for pgmeta' && sleep 3;
      done;
      su -s /bin/bash airflow -c \"PATH='/home/airflow/.local/bin:$${PATH}' airflow users create --username ${AIRFLOW_USER} --password ${AIRFLOW_PASSWORD} --firstname Admin --lastname User --role Admin --email admin@example.org\" || true
    "
  depends_on:
    pgmeta:
      condition: service_healthy

Часть 3: Влияние переименования контейнеров

Важно: Переименование контейнеров

При переименовании контейнеров (gp_airflow_webgp_airflow_webserver, gp_airflow_schgp_airflow_scheduler) необходимо учитывать:

  1. Имена сервисов в docker-compose.yml остаются без изменений

    • airflow-webserver, airflow-scheduler, airflow-init - это имена сервисов
    • Они используются в командах docker-compose logs, docker-compose restart и т.д.
    • Эти имена НЕ меняются
  2. Имена контейнеров меняются

    • gp_airflow_webgp_airflow_webserver
    • gp_airflow_schgp_airflow_scheduler
    • Они используются в командах docker exec, docker inspect, docker logs
  3. Проверка использования старых имён контейнеров

    # Поиск упоминаний старых имён в скриптах
    grep -r "gp_airflow_web" .
    grep -r "gp_airflow_sch" .
    
  4. Обновление Makefile (если используется)

    • Проверить команды, которые используют старые имена контейнеров
    • Пример: make logs может использовать docker-compose logs airflow-webserver (это корректно)
  5. Обновление документации

    • Обновить все упоминания имён контейнеров в README.md, TESTING.md
    • Обновить примеры команд в документации

Часть 4: План тестирования изменений

Этап 1: Подготовка окружения

  1. Остановить текущие контейнеры

    make down
    
  2. Удалить старые образы (опционально)

    docker rmi airflow-custom:latest
    
  3. Проверить наличие .env файла

    ls -la .env
    # Если отсутствует, скопировать из .env.example
    cp .env.example .env
    

Этап 2: Сборка новых образов

  1. Собрать образы с новым Dockerfile

    docker-compose build
    
  2. Проверить успешность сборки

    docker images | grep airflow-custom
    
  3. Проверить наличие LABEL

    docker inspect airflow-custom:latest | grep -A 10 "Labels"
    

Этап 3: Запуск сервисов

  1. Запустить весь стек

    make up
    
  2. Проверить статус контейнеров

    docker-compose ps
    
  3. Проверить логи инициализации

    docker-compose logs airflow-init
    

Этап 4: Проверка healthcheck

  1. Проверить healthcheck для airflow-webserver

    docker inspect gp_airflow_webserver | grep -A 20 "Health"
    
  2. Дождаться healthy статуса

    watch -n 2 'docker inspect --format="{{.State.Health.Status}}" gp_airflow_webserver'
    

Этап 5: Функциональное тестирование

  1. Проверить доступ к Airflow UI

    • Открыть http://localhost:8080
    • Проверить авторизацию (использовать креды из .env)
    • Проверить наличие DAG'ов в списке
  2. Проверить запуск DAG'ов

    • Выбрать любой DAG (например, bookings_to_gp_stage)
    • Запустить вручную через UI
    • Проверить успешность выполнения задач
  3. Проверить подключения к БД

    • Проверить Admin → Connections
    • Убедиться, что greenplum_conn и bookings_db доступны
    • Проверить Test Connection для каждого подключения
  4. Проверить логи scheduler

    docker-compose logs airflow-scheduler | tail -50
    

Этап 6: Проверка использования старых имён контейнеров

  1. Поиск упоминаний старых имён в проекте

    grep -r "gp_airflow_web" . --exclude-dir=.git --exclude-dir=__pycache__
    grep -r "gp_airflow_sch" . --exclude-dir=.git --exclude-dir=__pycache__
    
  2. Проверка Makefile

    grep -E "gp_airflow_web|gp_airflow_sch" Makefile
    
  3. Проверка документации

    grep -r "gp_airflow_web" README.md TESTING.md AGENTS.md docs/
    grep -r "gp_airflow_sch" README.md TESTING.md AGENTS.md docs/
    
  4. Обновление найденных упоминаний

    • Заменить gp_airflow_web на gp_airflow_webserver
    • Заменить gp_airflow_sch на gp_airflow_scheduler
    • Обновить примеры команд в документации

Этап 7: Тестирование требований

  1. Проверить установленные пакеты

    docker exec gp_airflow_webserver pip list | grep -E "psycopg2|pandas"
    
  2. Проверить совместимость пакетов

    docker exec gp_airflow_webserver pip check
    
  3. Проверить пользователя внутри контейнера

    docker exec gp_airflow_webserver whoami
    # Ожидаемый результат: airflow
    

Этап 8: Тестирование изменений requirements.txt

  1. Добавить тестовый пакет в requirements.txt

    echo "requests==2.31.0" >> airflow/requirements.txt
    
  2. Перезапустить контейнеры

    docker-compose restart airflow-webserver airflow-scheduler
    
  3. Проверить установку пакета

    docker exec gp_airflow_webserver pip list | grep requests
    
  4. Удалить тестовый пакет

    # Вернуть исходный requirements.txt
    git checkout airflow/requirements.txt
    

Этап 9: Регрессионное тестирование

  1. Запустить существующие тесты

    make test
    
  2. Проверить smoke-тесты DAG

    uv run pytest tests/test_dags_smoke.py -v
    
  3. Проверить тесты helpers

    uv run pytest tests/test_greenplum_helpers.py -v
    

Этап 10: Проверка после перезапуска

  1. Полный перезапуск стека

    make down
    make up
    
  2. Проверить сохранность данных

    • Проверить наличие DAG'ов в UI
    • Проверить историю запусков DAG'ов
    • Проверить подключения к БД
  3. Проверить логи на наличие ошибок

    docker-compose logs airflow-webserver | grep -i error
    docker-compose logs airflow-scheduler | grep -i error
    # Обратите внимание: имена сервисов не изменились, только имена контейнеров
    

Часть 5: Критерии успеха

Функциональные требования:

  • Все контейнеры успешно запускаются
  • Airflow UI доступен на http://localhost:8080
  • Авторизация работает корректно
  • Все DAG'ы отображаются в UI
  • DAG'и успешно выполняются
  • Подключения к Greenplum и bookings-db работают
  • Healthcheck для airflow-webserver работает корректно

Технические требования:

  • Образ собирается без ошибок
  • LABEL присутствуют в образе
  • Пакеты устанавливаются от пользователя airflow
  • pip check не возвращает ошибок
  • requirements.txt монтируется как volume
  • YAML anchors работают корректно
  • Нет дублирования конфигурации

Требования к совместимости:

  • Существующие тесты проходят успешно
  • Данные сохраняются после перезапуска
  • История запусков DAG'ов сохраняется
  • Подключения к БД работают как раньше

Часть 6: Откат изменений

Если изменения вызывают проблемы, план отката:

  1. Остановить контейнеры

    make down
    
  2. Вернуть старые файлы

    git checkout Dockerfile docker-compose.yml
    
  3. Удалить новый образ

    docker rmi airflow-custom:latest
    
  4. Перезапустить стек

    make up
    

Часть 7: Документация

После успешного внедрения изменений необходимо обновить:

  1. README.md - добавить информацию о новом Dockerfile
  2. AGENTS.md - обновить инструкции для агентов
  3. Комментарии в docker-compose.yml - добавить пояснения к YAML anchors

Резюме

План включает:

  • 2 файла для изменения: DockerfileDockerfile.airflow, docker-compose.yml
  • 10 этапов тестирования
  • 12 функциональных критериев успеха
  • План отката на случай проблем
  • Переименование контейнеров для улучшения читаемости
  • Проверка использования старых имён контейнеров в проекте

Важные замечания:

  1. Имена сервисов НЕ меняются - airflow-webserver, airflow-scheduler, airflow-init
  2. Имена контейнеров меняются - gp_airflow_webgp_airflow_webserver, gp_airflow_schgp_airflow_scheduler
  3. Необходимо проверить использование старых имён контейнеров в скриптах и документации
  4. Makefile команды используют имена сервисов, поэтому они продолжат работать без изменений

Все изменения следуют best practices для Docker и Airflow, сохраняют обратную совместимость и не требуют изменений в DAG'ах.