- Зачем: - Пример базовой загрузки 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-ов не затронуты).
17 KiB
План улучшения Dockerfile и docker-compose.yml
Обзор
Документ описывает план улучшения Dockerfile для Airflow и его интеграции с docker-compose.yml на основе анализа best practices.
Согласованные изменения
✅ Переименовать Dockerfile → Dockerfile.airflow
✅ Обновить build: . → build: { context: ., dockerfile: Dockerfile.airflow }
✅ Добавить YAML anchors для устранения дублирования конфигурации
✅ Добавить healthcheck для airflow-webserver
✅ Исправить расположение requirements.txt в Dockerfile
✅ Добавить LABEL в Dockerfile
✅ Добавить USER airflow после установки зависимостей
✅ Добавить проверку pip check
✅ Переименовать контейнеры (gp_airflow_web → gp_airflow_webserver, gp_airflow_sch → gp_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
Обоснование изменений:
- LABEL - стандартная практика для документирования образов
/opt/airflow/requirements.txt- стандартное расположение для Airflowpip check- проверка совместимости установленных пакетовUSER airflow- безопасность и соответствие best practicesWORKDIR /opt/airflow- явное указание рабочей директории
Часть 2: Изменения в docker-compose.yml
Основные изменения:
- Добавить YAML anchors для устранения дублирования
- Обновить build для всех Airflow сервисов
- Добавить healthcheck для airflow-webserver
- Добавить комментарии для пояснения сокращений в именах контейнеров
Структура 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_web → gp_airflow_webserver, gp_airflow_sch → gp_airflow_scheduler) необходимо учитывать:
-
Имена сервисов в docker-compose.yml остаются без изменений
airflow-webserver,airflow-scheduler,airflow-init- это имена сервисов- Они используются в командах
docker-compose logs,docker-compose restartи т.д. - Эти имена НЕ меняются
-
Имена контейнеров меняются
gp_airflow_web→gp_airflow_webservergp_airflow_sch→gp_airflow_scheduler- Они используются в командах
docker exec,docker inspect,docker logs
-
Проверка использования старых имён контейнеров
# Поиск упоминаний старых имён в скриптах grep -r "gp_airflow_web" . grep -r "gp_airflow_sch" . -
Обновление Makefile (если используется)
- Проверить команды, которые используют старые имена контейнеров
- Пример:
make logsможет использоватьdocker-compose logs airflow-webserver(это корректно)
-
Обновление документации
- Обновить все упоминания имён контейнеров в README.md, TESTING.md
- Обновить примеры команд в документации
Часть 4: План тестирования изменений
Этап 1: Подготовка окружения
-
Остановить текущие контейнеры
make down -
Удалить старые образы (опционально)
docker rmi airflow-custom:latest -
Проверить наличие .env файла
ls -la .env # Если отсутствует, скопировать из .env.example cp .env.example .env
Этап 2: Сборка новых образов
-
Собрать образы с новым Dockerfile
docker-compose build -
Проверить успешность сборки
docker images | grep airflow-custom -
Проверить наличие LABEL
docker inspect airflow-custom:latest | grep -A 10 "Labels"
Этап 3: Запуск сервисов
-
Запустить весь стек
make up -
Проверить статус контейнеров
docker-compose ps -
Проверить логи инициализации
docker-compose logs airflow-init
Этап 4: Проверка healthcheck
-
Проверить healthcheck для airflow-webserver
docker inspect gp_airflow_webserver | grep -A 20 "Health" -
Дождаться healthy статуса
watch -n 2 'docker inspect --format="{{.State.Health.Status}}" gp_airflow_webserver'
Этап 5: Функциональное тестирование
-
Проверить доступ к Airflow UI
- Открыть http://localhost:8080
- Проверить авторизацию (использовать креды из .env)
- Проверить наличие DAG'ов в списке
-
Проверить запуск DAG'ов
- Выбрать любой DAG (например,
bookings_to_gp_stage) - Запустить вручную через UI
- Проверить успешность выполнения задач
- Выбрать любой DAG (например,
-
Проверить подключения к БД
- Проверить Admin → Connections
- Убедиться, что
greenplum_connиbookings_dbдоступны - Проверить Test Connection для каждого подключения
-
Проверить логи scheduler
docker-compose logs airflow-scheduler | tail -50
Этап 6: Проверка использования старых имён контейнеров
-
Поиск упоминаний старых имён в проекте
grep -r "gp_airflow_web" . --exclude-dir=.git --exclude-dir=__pycache__ grep -r "gp_airflow_sch" . --exclude-dir=.git --exclude-dir=__pycache__ -
Проверка Makefile
grep -E "gp_airflow_web|gp_airflow_sch" Makefile -
Проверка документации
grep -r "gp_airflow_web" README.md TESTING.md AGENTS.md docs/ grep -r "gp_airflow_sch" README.md TESTING.md AGENTS.md docs/ -
Обновление найденных упоминаний
- Заменить
gp_airflow_webнаgp_airflow_webserver - Заменить
gp_airflow_schнаgp_airflow_scheduler - Обновить примеры команд в документации
- Заменить
Этап 7: Тестирование требований
-
Проверить установленные пакеты
docker exec gp_airflow_webserver pip list | grep -E "psycopg2|pandas" -
Проверить совместимость пакетов
docker exec gp_airflow_webserver pip check -
Проверить пользователя внутри контейнера
docker exec gp_airflow_webserver whoami # Ожидаемый результат: airflow
Этап 8: Тестирование изменений requirements.txt
-
Добавить тестовый пакет в requirements.txt
echo "requests==2.31.0" >> airflow/requirements.txt -
Перезапустить контейнеры
docker-compose restart airflow-webserver airflow-scheduler -
Проверить установку пакета
docker exec gp_airflow_webserver pip list | grep requests -
Удалить тестовый пакет
# Вернуть исходный requirements.txt git checkout airflow/requirements.txt
Этап 9: Регрессионное тестирование
-
Запустить существующие тесты
make test -
Проверить smoke-тесты DAG
uv run pytest tests/test_dags_smoke.py -v -
Проверить тесты helpers
uv run pytest tests/test_greenplum_helpers.py -v
Этап 10: Проверка после перезапуска
-
Полный перезапуск стека
make down make up -
Проверить сохранность данных
- Проверить наличие DAG'ов в UI
- Проверить историю запусков DAG'ов
- Проверить подключения к БД
-
Проверить логи на наличие ошибок
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: Откат изменений
Если изменения вызывают проблемы, план отката:
-
Остановить контейнеры
make down -
Вернуть старые файлы
git checkout Dockerfile docker-compose.yml -
Удалить новый образ
docker rmi airflow-custom:latest -
Перезапустить стек
make up
Часть 7: Документация
После успешного внедрения изменений необходимо обновить:
- README.md - добавить информацию о новом Dockerfile
- AGENTS.md - обновить инструкции для агентов
- Комментарии в docker-compose.yml - добавить пояснения к YAML anchors
Резюме
План включает:
- 2 файла для изменения:
Dockerfile→Dockerfile.airflow,docker-compose.yml - 10 этапов тестирования
- 12 функциональных критериев успеха
- План отката на случай проблем
- Переименование контейнеров для улучшения читаемости
- Проверка использования старых имён контейнеров в проекте
Важные замечания:
- Имена сервисов НЕ меняются -
airflow-webserver,airflow-scheduler,airflow-init - Имена контейнеров меняются -
gp_airflow_web→gp_airflow_webserver,gp_airflow_sch→gp_airflow_scheduler - Необходимо проверить использование старых имён контейнеров в скриптах и документации
- Makefile команды используют имена сервисов, поэтому они продолжат работать без изменений
Все изменения следуют best practices для Docker и Airflow, сохраняют обратную совместимость и не требуют изменений в DAG'ах.