Перейти к содержимому
TelegramGitHub

Open source за минуты

Почти любой инструмент данных можно запустить в контейнере. Одна команда или один compose.yaml. Ничего не нужно ставить на ноутбук.

  • Изоляция. Airflow, dbt и Jupyter требуют разные версии Python и библиотек. В контейнерах они не мешают друг другу.
  • Одинаковое окружение. У вас, у коллеги и в CI работает один и тот же образ. Фраза «у меня работает» не нужна.
  • Одноразовость. Попробовали инструмент, удалили контейнер. Ноутбук остался чистым.
  • Несколько версий рядом. postgres:15 и postgres:17 работают одновременно на разных портах.
  • Быстрый старт команды. Новый коллега делает git clone и docker compose up. Окружение готово.
ШаблонКогдаКак
Разовый инструментЗапустить команду и забытьdocker run --rm ...
СервисБаза, BI, оркестратор. Работает долгоcompose.yaml, docker compose up -d
Своя задачаВаш пайплайн или скриптDockerfile и docker build
ИнструментОбразДля чего
Postgrespostgres:17База данных для пайплайнов и тестов
Admineradminer:5Лёгкий веб-клиент для баз
Metabasemetabase/metabase:v0.65.4BI: графики и дашборды
Supersetapache/superset:6.1.0BI. Нужна дополнительная настройка
Airflowофициальный docker-compose.yamlОркестрация пайплайнов
dbtсвой образ (ниже)Трансформации в SQL
Jupyterquay.io/jupyter/scipy-notebook:python-3.12Ноутбуки для анализа
ClickHouseclickhouse/clickhouse-server:26.8Колоночная база для аналитики
Kafkaapache/kafka:4.4.0Потоки событий
MLflowghcr.io/mlflow/mlflow:v3.5.0Учёт ML-экспериментов

Мы проверили, что эти теги существуют (docker manifest inspect). Версии быстро устаревают. Перед работой откройте страницу образа на Docker Hub и выберите свежий тег.

Не нужно ставить Python. Подключите папку и запустите скрипт в готовом образе:

Окно терминала
cd ~/docker-practice
docker run --rm -v "$PWD:/work" -w /work \
-e ORDERS_PATH=/work/data/orders.csv \
python:3.12-slim python app/report.py

Ответ:

Файл: /work/data/orders.csv
Заказов: 500
Выручка по каналам (только completed):
organic 23715.82
ads 23082.74
email 15459.67
  • -v "$PWD:/work" подключает текущую папку в контейнер.
  • -w /work делает /work рабочей папкой.
  • --rm удаляет контейнер после выхода.

Так же запускают DuckDB, jq, psql и любые другие утилиты. Ставить их не нужно.

Подробно compose разобран в уроке про Compose. Пример с пином версии:

services:
db:
image: postgres:17
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
adminer:
image: adminer:5
ports:
- "8080:8080"
volumes:
pgdata:

Всегда пишите версию образа. Не используйте latest: завтра он может стать другим.

Airflow состоит из нескольких сервисов. Писать их вручную не нужно: у проекта есть готовый docker-compose.yaml. Мы проверили, что ссылка ниже работает. Он из официальной документации и может измениться. Открывайте страницу Airflow про Docker Compose и берите версию оттуда.

Окно терминала
mkdir airflow && cd airflow
curl -LfO https://airflow.apache.org/docs/apache-airflow/3.4.0/docker-compose.yaml
mkdir -p ./dags ./logs ./plugins ./config
echo "AIRFLOW_UID=$(id -u)" > .env
docker compose up airflow-init
docker compose up
  • airflow-init создаёт базу и пользователя. Это разовый шаг.
  • Веб-интерфейс: http://localhost:8080. Логин и пароль по умолчанию написаны в официальной инструкции.
  • Свои DAG кладите в папку dags.
  • Это окружение для обучения. В продакшене так не запускают: смотрите урок про продакшен.

В файле восемь сервисов. Список мы получили командой docker compose config --services:

postgres redis airflow-init airflow-apiserver airflow-dag-processor airflow-scheduler airflow-triggerer airflow-worker

Официальный образ ghcr.io/dbt-labs/dbt-postgres не собран для arm64. На Mac с чипом Apple (M1 и новее) он не запускается:

docker: no matching manifest for linux/arm64/v8 in the manifest list entries

Решение: свой образ из python:3.12-slim. Он работает на любой архитектуре.

FROM python:3.12-slim
RUN pip install --no-cache-dir dbt-core==1.12.6 dbt-postgres==1.11.0
WORKDIR /project
ENTRYPOINT ["dbt"]

Версию dbt-core нужно закрепить. Мы поставили только dbt-postgres==1.11.0, и pip взял dbt-core 1.13.0-b1. Это бета-версия.

Сервис в compose.yaml. Он запускается только по просьбе (profiles):

dbt:
build: ./dbt
profiles: ["tools"]
environment:
DB_PASSWORD: ${DB_PASSWORD}
DBT_PROFILES_DIR: /project
volumes:
- ./dbt:/project
depends_on:
db:
condition: service_healthy

Запуск:

Окно терминала
docker compose run --rm dbt run

Результат на наших данных. Модель revenue_by_channel создала представление в схеме analytics:

1 of 1 OK created sql view model analytics.revenue_by_channel ... [CREATE VIEW in 0.04s]
Done. PASS=1 WARN=0 ERROR=0 SKIP=0 NO-OP=0 REUSED=0 TOTAL=1

Полный пример со всеми файлами — в уроке Compose для пайплайна.

Почти у каждого open source проекта есть публичный образ и готовый пример запуска. Это быстрый способ попробовать инструмент. Мы проверили, какие архитектуры у образов (ноябрь 2026).

ИнструментЧто этоОбраз или стартерMac с Apple (arm64)
AirflowОркестраторapache/airflow:3.4.0 и официальный docker-compose.yaml (выше)Да
PrefectОркестратор на Pythonprefecthq/prefect:3-latestДа
DagsterОркестратор, ориентирован на данныеОфициальный пример deploy_dockerДа
KestraОркестратор, потоки в YAMLОфициальный docker-compose.ymlДа
MageПайплайны в ноутбукеmageai/mageai, инструкцияДа
MeltanoELT на Singermeltano/meltanoДа
dbtТрансформации в SQLghcr.io/dbt-labs/dbt-core, dbt-postgres, dbt-snowflake, dbt-bigqueryНет, только amd64. Соберите свой образ
SupersetBIapache/superset:6.1.0, репозиторийДа
LightdashBI поверх dbtlightdash/lightdashНет, только amd64
TrinoЗапросы к разным источникамtrinodb/trinoДа
SparkОбработка больших данныхapache/sparkДа
RedpandaKafka-совместимый брокерredpandadata/redpandaДа
GrafanaМониторинг и графикиgrafana/grafanaДа

Как читать столбец arm64: если написано «только amd64», на Mac с чипом M образ запустится только через эмуляцию (--platform linux/amd64). Это медленно. Для dbt лучше собрать свой образ.

Мы запустили этот пример. Сервер Prefect с веб-интерфейсом:

Окно терминала
docker run -d --name prefect -p 4200:4200 \
prefecthq/prefect:3-latest \
prefect server start --host 0.0.0.0

Проверка:

Окно терминала
curl -s localhost:4200/api/health

Ответ: true. Интерфейс: http://localhost:4200. Остановить и удалить: docker rm -f prefect.

--host 0.0.0.0 нужен, чтобы сервер слушал не только внутри контейнера. Без него порт -p не сработает.

Образ большой (сотни мегабайт). Тег 3-latest меняется. Для своего проекта закрепите точную версию.

  • Официальный пример. Ищите в документации раздел Docker, Docker Compose или Self-hosted.
  • Версии образов. В примерах часто стоит latest. Замените его на конкретную версию.
  • Пароли. В стартерах стоят пароли для обучения. Не берите их в продакшен.
  • Данные. Проверьте, где пример хранит данные. Если тома нет, данные пропадут при удалении контейнера.
  • Размер. Стартеры оркестраторов поднимают 4–8 контейнеров. Им нужно 4 ГБ памяти и больше.

Для них мы только проверили образ. Запускать их целиком не будем.

  • Kafka. Один брокер для опытов. Команда из официальной документации:
    Окно терминала
    docker run -p 9092:9092 apache/kafka:4.4.0
  • Jupyter. Образ большой, несколько гигабайт. Порт 8888, папку с ноутбуками подключают через -v.
  • ClickHouse. Образ clickhouse/clickhouse-server:26.8. Данные храните в томе: -v ch-data:/var/lib/clickhouse.
  • MLflow. Образ ghcr.io/mlflow/mlflow:v3.5.0. Сервер учёта экспериментов на порту 5000.
  • Superset. Нужны база, секретный ключ и первый запуск с созданием пользователя. Следуйте официальной инструкции.
  • Тесты пайплайна. CI запускает тот же образ, что и продакшен. Тест проходит в том же окружении.
  • Тесты с базой. В CI поднимают postgres:17 как сервис, грузят тестовые данные, проверяют SQL.
  • Новый коллега. git clone, cp .env.example .env, docker compose up. Через пять минут всё работает.

Задания 1 и 3 — в папке ~/docker-practice. Для задания 2 создайте отдельную папку, чтобы не перезаписать compose.yaml из прошлых уроков.

Запустите app/report.py в одноразовом контейнере python:3.12-slim, без Dockerfile. Подключите текущую папку через -v.

Проверка: в выводе Заказов: 500 и три строки по каналам: organic 23715.82, ads 23082.74, email 15459.67.

Решение
Окно терминала
cd ~/docker-practice
docker run --rm -v "$PWD:/work" -w /work \
-e ORDERS_PATH=/work/data/orders.csv \
python:3.12-slim python app/report.py

Без -e ORDERS_PATH скрипт ищет файл /data/orders.csv и падает с FileNotFoundError.

Найдите образ Adminer на Docker Hub и посмотрите его теги. Закрепите версию 5 и напишите сервис для compose.yaml на порту 8080. Проверьте файл командой docker compose config -q.

Проверка: команда docker compose config -q ничего не печатает и возвращает код 0 (echo $? показывает 0).

Решение

Теги: hub.docker.com/_/adminer/tags. Создайте отдельную папку:

Окно терминала
mkdir -p ~/adminer-try && cd ~/adminer-try

Файл compose.yaml в ней:

services:
adminer:
image: adminer:5
ports:
- "8080:8080"
Окно терминала
docker compose config -q
echo $?

Если порт 8080 занят, поменяйте левую часть: "8081:8080".

Скачайте официальный docker-compose.yaml Airflow и выведите список его сервисов. Ничего не запускайте.

Проверка: в списке 8 сервисов, среди них airflow-scheduler и airflow-apiserver.

Решение
Окно терминала
mkdir -p ~/airflow-look && cd ~/airflow-look
curl -LfO https://airflow.apache.org/docs/apache-airflow/3.4.0/docker-compose.yaml
docker compose config --services 2>/dev/null

2>/dev/null прячет предупреждения о пустых переменных (FERNET_KEY, AIRFLOW_UID). Команда только читает файл. Контейнеры не стартуют. Если файл сменился, список может отличаться.

Дальше: Контейнеры в продакшене.