Убрать из compose.yaml параметризацию, которой нечего параметризовать, а
оставшейся дать явный отказ вместо тихой подстановки.
Сейчас в compose.yaml44 подстановки на 35 имён, и у каждой стоит :-умолчание. Все 35 имён продублированы в .env.example. То есть каждое
значение стенда написано в git дважды — умолчанием в compose.yaml и строкой
в образце, — и эти две записи могут разъехаться молча. Сегодня они сходятся;
завтра кто-то поднимет версию в одном месте.
Вторая половина беды в том, что часть имён параметризует вещи, у которых
осмысленное значение ровно одно. ${KAFKA_IMAGE:-apache/kafka:4.3.1} читается
как «версия бывает разной», хотя стенд рассчитан на одну.
Правило — двухступенчатое
1. У вещи ровно одно значение → литерал в compose.yaml. Ни .env, ни ${...}. Версия образа не настройка, а часть того, чем стенд является;
менять её локально и молча незачем.
2. Вещь честно разная по машинам → в .env, и .env обязателен. Форма ${X:?текст ошибки} — без умолчания. Умолчание здесь именно вредно: оно
прячет незаявленную переменную вместо того, чтобы упасть. .env заводится
копированием образца, и это первый шаг быстрого старта.
Учебная сторона второго пункта: cp .env.example .env заставляет менти
открыть файл и увидеть, какие у стенда ручки. Запуск «вообще без настройки»
это прячет.
Образец уже в репозитории. База образа генератора после #41 записана
литералом (FROM python:3.14.7-slim), без ARG и без .env — ровно по
первому пункту. Тем же тикетом решено: базовый образ принадлежит тому же
закреплённому набору, что и uv.lock, и в неотслеживаемом файле ему не место.
Инвентарь: все 35 имён
Счёт снят с compose.yaml на момент заведения тикета. Разбиение по корзинам —
предложение, а не приговор: спорные случаи решаются при исполнении.
Корзина 1 — одно значение, в литерал (9 имён, 12 подстановок)
Стенд поднимают и на VPS — пароль там менять надо.
Отдельным пунктом: базы собираемых образов
infra/airflow/Dockerfile и infra/superset/Dockerfile начинаются с ARG X_BASE_IMAGEбез умолчания, а FROM берёт значение оттуда. Две
беды разом:
Dockerfile перестал быть самодостаточным описанием сборки — голая docker build не работает, нужен --build-arg, а вторая половина описания
живёт в compose.yaml;
версия базы написана дважды, в умолчании compose.yaml и в .env.example.
Перевести обе на литерал, как сделано у генератора. Проверки scripts/config-test.sh:74-82, требующие строк ARG SUPERSET_BASE_IMAGE и ARG AIRFLOW_BASE_IMAGE, при этом снимаются — они сторожат именно ту
конструкцию, которую убираем.
Что придётся поправить следом
README, раздел «Быстрый старт». Фраза «Стенд запускается без .env»
перестаёт быть верной; cp .env.example .env становится первым шагом.
README про образец. Сейчас там: «.env.example — справочник, а не
настройка». После правки он ровно настройка, и это надо сказать прямо.
scripts/config-test.sh — снять две проверки ARG *_BASE_IMAGE.
Критерии приёмки
Имена корзины 1 в compose.yaml заменены литералами; из .env.example
удалены. Значения при этом не изменились ни у одного.
Имена корзины 2 переведены на ${X:?текст} без умолчания; текст ошибки
называет, что делать (скопировать образец).
docker compose config без .env падает внятно, а не собирает
конфигурацию с пустыми значениями.
Базы infra/airflow/Dockerfile и infra/superset/Dockerfile записаны
литералом; ARG *_BASE_IMAGE и парные проверки в config-test.sh сняты;
голая docker build для обоих работает.
Ни одно имя не объявлено в двух местах разом: сверка compose.yaml
против .env.example пустая в обе стороны.
README поправлен: первым шагом копирование образца, формулировка про
«справочник, а не настройка» заменена.
make up с нуля, make smoke, make check-clickhouse, make check-services зелёные после копирования образца.
Границы
Значения не меняются — меняется только место, где они написаны. Ни одной
версии не поднимать: это отдельная работа.
Генератор уже приведён к правилу тикетом #41, его Dockerfile не трогать.
Секреты как таковые не пересматриваются: учебные пароли остаются учебными,
вопрос только в том, где они объявлены.
Состав служб не меняется.
Сначала прочитать
compose.yaml целиком — инвентарь выше снят с него.
.env.example — 26 имён локальной настройки, все читаются Compose.
generator/Dockerfile — образец правила, разобранный при #41.
scripts/config-test.sh, строки 74–82 — проверки, которые снимаются.
README, разделы «Быстрый старт» и абзац про .env.example.
Проверка
make config-test
docker compose config без .env — ожидается внятное падение
cp .env.example .env, затем make up с нуля
make smoke, make check-clickhouse, make check-services
## Цель
Убрать из `compose.yaml` параметризацию, которой нечего параметризовать, а
оставшейся дать явный отказ вместо тихой подстановки.
Сейчас в `compose.yaml` **44 подстановки на 35 имён, и у каждой стоит
`:-умолчание`**. Все 35 имён продублированы в `.env.example`. То есть каждое
значение стенда написано в git дважды — умолчанием в `compose.yaml` и строкой
в образце, — и эти две записи могут разъехаться молча. Сегодня они сходятся;
завтра кто-то поднимет версию в одном месте.
Вторая половина беды в том, что часть имён параметризует вещи, у которых
осмысленное значение ровно одно. `${KAFKA_IMAGE:-apache/kafka:4.3.1}` читается
как «версия бывает разной», хотя стенд рассчитан на одну.
## Правило — двухступенчатое
**1. У вещи ровно одно значение → литерал в `compose.yaml`.** Ни `.env`, ни
`${...}`. Версия образа не настройка, а часть того, чем стенд является;
менять её локально и молча незачем.
**2. Вещь честно разная по машинам → в `.env`, и `.env` обязателен.** Форма
`${X:?текст ошибки}` — без умолчания. Умолчание здесь именно вредно: оно
прячет незаявленную переменную вместо того, чтобы упасть. `.env` заводится
копированием образца, и это первый шаг быстрого старта.
Учебная сторона второго пункта: `cp .env.example .env` заставляет менти
открыть файл и увидеть, какие у стенда ручки. Запуск «вообще без настройки»
это прячет.
**Образец уже в репозитории.** База образа генератора после #41 записана
литералом (`FROM python:3.14.7-slim`), без `ARG` и без `.env` — ровно по
первому пункту. Тем же тикетом решено: базовый образ принадлежит тому же
закреплённому набору, что и `uv.lock`, и в неотслеживаемом файле ему не место.
## Инвентарь: все 35 имён
Счёт снят с `compose.yaml` на момент заведения тикета. Разбиение по корзинам —
предложение, а не приговор: спорные случаи решаются при исполнении.
### Корзина 1 — одно значение, в литерал (9 имён, 12 подстановок)
| Имя | Подстановок | Значение |
|---|---|---|
| `CLICKHOUSE_IMAGE` | 3 | `clickhouse/clickhouse-server:26.3.17.56` |
| `KAFKA_IMAGE` | 2 | `apache/kafka:4.3.1` |
| `AIRFLOW_IMAGE` | 1 | `apache/airflow:3.3.0` |
| `SUPERSET_IMAGE` | 1 | `apache/superset:6.1.0` |
| `POSTGRES_IMAGE` | 1 | `postgres:16-alpine` |
| `PROMETHEUS_IMAGE` | 1 | `prom/prometheus:v3.13.2` |
| `GRAFANA_IMAGE` | 1 | `grafana/grafana:13.1.1` |
| `KAFKA_BOOTSTRAP_SERVERS` | 1 | `kafka:9092` — внутренний адрес сети Compose |
| `KAFKA_TOPIC` | 1 | `hits` — имя топика этого стенда |
### Корзина 2 — экземпляр и внешние порты (10 имён, 11 подстановок)
`COMPOSE_PROJECT_NAME` (1), `KAFKA_EXTERNAL_PORT` (2), `CLICKHOUSE_01_HTTP_PORT`, `CLICKHOUSE_01_TCP_PORT`,
`CLICKHOUSE_02_HTTP_PORT`, `CLICKHOUSE_02_TCP_PORT`, `AIRFLOW_PORT`,
`SUPERSET_PORT`, `PROMETHEUS_PORT`, `GRAFANA_PORT`.
Здесь параметризация окупается: внешний порт конфликтует с чужим софтом на конкретной
машине, а имя проекта отличает друг от друга две копии стенда.
### Корзина 2 — учётные данные и секреты (16 имён, 21 подстановка)
`POSTGRES_ADMIN_USER`, `POSTGRES_ADMIN_PASSWORD`, `AIRFLOW_METADATA_USER` (2),
`AIRFLOW_METADATA_PASSWORD` (2), `AIRFLOW_ADMIN_USER` (2),
`AIRFLOW_ADMIN_PASSWORD`, `AIRFLOW_JWT_SECRET`, `AIRFLOW_API_SECRET_KEY`,
`AIRFLOW_FERNET_KEY`, `SUPERSET_METADATA_USER` (2),
`SUPERSET_METADATA_PASSWORD` (2), `SUPERSET_ADMIN_USER`,
`SUPERSET_ADMIN_PASSWORD`, `SUPERSET_SECRET_KEY`, `GRAFANA_ADMIN_USER`,
`GRAFANA_ADMIN_PASSWORD`.
Стенд поднимают и на VPS — пароль там менять надо.
## Отдельным пунктом: базы собираемых образов
`infra/airflow/Dockerfile` и `infra/superset/Dockerfile` начинаются с
`ARG X_BASE_IMAGE` **без умолчания**, а `FROM` берёт значение оттуда. Две
беды разом:
- `Dockerfile` перестал быть самодостаточным описанием сборки — голая
`docker build` не работает, нужен `--build-arg`, а вторая половина описания
живёт в `compose.yaml`;
- версия базы написана дважды, в умолчании `compose.yaml` и в `.env.example`.
Перевести обе на литерал, как сделано у генератора. Проверки
`scripts/config-test.sh:74-82`, требующие строк `ARG SUPERSET_BASE_IMAGE` и
`ARG AIRFLOW_BASE_IMAGE`, при этом снимаются — они сторожат именно ту
конструкцию, которую убираем.
## Что придётся поправить следом
- **README, раздел «Быстрый старт».** Фраза «Стенд запускается без `.env`»
перестаёт быть верной; `cp .env.example .env` становится первым шагом.
- **README про образец.** Сейчас там: «`.env.example` — справочник, а не
настройка». После правки он ровно настройка, и это надо сказать прямо.
- **`scripts/config-test.sh`** — снять две проверки `ARG *_BASE_IMAGE`.
## Критерии приёмки
- [ ] Имена корзины 1 в `compose.yaml` заменены литералами; из `.env.example`
удалены. Значения при этом не изменились ни у одного.
- [ ] Имена корзины 2 переведены на `${X:?текст}` без умолчания; текст ошибки
называет, что делать (скопировать образец).
- [ ] `docker compose config` без `.env` падает внятно, а не собирает
конфигурацию с пустыми значениями.
- [ ] Базы `infra/airflow/Dockerfile` и `infra/superset/Dockerfile` записаны
литералом; `ARG *_BASE_IMAGE` и парные проверки в `config-test.sh` сняты;
голая `docker build` для обоих работает.
- [ ] Ни одно имя не объявлено в двух местах разом: сверка `compose.yaml`
против `.env.example` пустая в обе стороны.
- [ ] README поправлен: первым шагом копирование образца, формулировка про
«справочник, а не настройка» заменена.
- [ ] `make up` с нуля, `make smoke`, `make check-clickhouse`,
`make check-services` зелёные после копирования образца.
## Границы
- **Значения не меняются** — меняется только место, где они написаны. Ни одной
версии не поднимать: это отдельная работа.
- Генератор уже приведён к правилу тикетом #41, его `Dockerfile` не трогать.
- Секреты как таковые не пересматриваются: учебные пароли остаются учебными,
вопрос только в том, где они объявлены.
- Состав служб не меняется.
## Сначала прочитать
- `compose.yaml` целиком — инвентарь выше снят с него.
- `.env.example` — 26 имён локальной настройки, все читаются Compose.
- `generator/Dockerfile` — образец правила, разобранный при #41.
- `scripts/config-test.sh`, строки 74–82 — проверки, которые снимаются.
- README, разделы «Быстрый старт» и абзац про `.env.example`.
## Проверка
- `make config-test`
- `docker compose config` без `.env` — ожидается внятное падение
- `cp .env.example .env`, затем `make up` с нуля
- `make smoke`, `make check-clickhouse`, `make check-services`
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Цель
Убрать из
compose.yamlпараметризацию, которой нечего параметризовать, аоставшейся дать явный отказ вместо тихой подстановки.
Сейчас в
compose.yaml44 подстановки на 35 имён, и у каждой стоит:-умолчание. Все 35 имён продублированы в.env.example. То есть каждоезначение стенда написано в git дважды — умолчанием в
compose.yamlи строкойв образце, — и эти две записи могут разъехаться молча. Сегодня они сходятся;
завтра кто-то поднимет версию в одном месте.
Вторая половина беды в том, что часть имён параметризует вещи, у которых
осмысленное значение ровно одно.
${KAFKA_IMAGE:-apache/kafka:4.3.1}читаетсякак «версия бывает разной», хотя стенд рассчитан на одну.
Правило — двухступенчатое
1. У вещи ровно одно значение → литерал в
compose.yaml. Ни.env, ни${...}. Версия образа не настройка, а часть того, чем стенд является;менять её локально и молча незачем.
2. Вещь честно разная по машинам → в
.env, и.envобязателен. Форма${X:?текст ошибки}— без умолчания. Умолчание здесь именно вредно: онопрячет незаявленную переменную вместо того, чтобы упасть.
.envзаводитсякопированием образца, и это первый шаг быстрого старта.
Учебная сторона второго пункта:
cp .env.example .envзаставляет ментиоткрыть файл и увидеть, какие у стенда ручки. Запуск «вообще без настройки»
это прячет.
Образец уже в репозитории. База образа генератора после #41 записана
литералом (
FROM python:3.14.7-slim), безARGи без.env— ровно попервому пункту. Тем же тикетом решено: базовый образ принадлежит тому же
закреплённому набору, что и
uv.lock, и в неотслеживаемом файле ему не место.Инвентарь: все 35 имён
Счёт снят с
compose.yamlна момент заведения тикета. Разбиение по корзинам —предложение, а не приговор: спорные случаи решаются при исполнении.
Корзина 1 — одно значение, в литерал (9 имён, 12 подстановок)
CLICKHOUSE_IMAGEclickhouse/clickhouse-server:26.3.17.56KAFKA_IMAGEapache/kafka:4.3.1AIRFLOW_IMAGEapache/airflow:3.3.0SUPERSET_IMAGEapache/superset:6.1.0POSTGRES_IMAGEpostgres:16-alpinePROMETHEUS_IMAGEprom/prometheus:v3.13.2GRAFANA_IMAGEgrafana/grafana:13.1.1KAFKA_BOOTSTRAP_SERVERSkafka:9092— внутренний адрес сети ComposeKAFKA_TOPIChits— имя топика этого стендаКорзина 2 — экземпляр и внешние порты (10 имён, 11 подстановок)
COMPOSE_PROJECT_NAME(1),KAFKA_EXTERNAL_PORT(2),CLICKHOUSE_01_HTTP_PORT,CLICKHOUSE_01_TCP_PORT,CLICKHOUSE_02_HTTP_PORT,CLICKHOUSE_02_TCP_PORT,AIRFLOW_PORT,SUPERSET_PORT,PROMETHEUS_PORT,GRAFANA_PORT.Здесь параметризация окупается: внешний порт конфликтует с чужим софтом на конкретной
машине, а имя проекта отличает друг от друга две копии стенда.
Корзина 2 — учётные данные и секреты (16 имён, 21 подстановка)
POSTGRES_ADMIN_USER,POSTGRES_ADMIN_PASSWORD,AIRFLOW_METADATA_USER(2),AIRFLOW_METADATA_PASSWORD(2),AIRFLOW_ADMIN_USER(2),AIRFLOW_ADMIN_PASSWORD,AIRFLOW_JWT_SECRET,AIRFLOW_API_SECRET_KEY,AIRFLOW_FERNET_KEY,SUPERSET_METADATA_USER(2),SUPERSET_METADATA_PASSWORD(2),SUPERSET_ADMIN_USER,SUPERSET_ADMIN_PASSWORD,SUPERSET_SECRET_KEY,GRAFANA_ADMIN_USER,GRAFANA_ADMIN_PASSWORD.Стенд поднимают и на VPS — пароль там менять надо.
Отдельным пунктом: базы собираемых образов
infra/airflow/Dockerfileиinfra/superset/Dockerfileначинаются сARG X_BASE_IMAGEбез умолчания, аFROMберёт значение оттуда. Двебеды разом:
Dockerfileперестал быть самодостаточным описанием сборки — голаяdocker buildне работает, нужен--build-arg, а вторая половина описанияживёт в
compose.yaml;compose.yamlи в.env.example.Перевести обе на литерал, как сделано у генератора. Проверки
scripts/config-test.sh:74-82, требующие строкARG SUPERSET_BASE_IMAGEиARG AIRFLOW_BASE_IMAGE, при этом снимаются — они сторожат именно туконструкцию, которую убираем.
Что придётся поправить следом
.env»перестаёт быть верной;
cp .env.example .envстановится первым шагом..env.example— справочник, а ненастройка». После правки он ровно настройка, и это надо сказать прямо.
scripts/config-test.sh— снять две проверкиARG *_BASE_IMAGE.Критерии приёмки
compose.yamlзаменены литералами; из.env.exampleудалены. Значения при этом не изменились ни у одного.
${X:?текст}без умолчания; текст ошибкиназывает, что делать (скопировать образец).
docker compose configбез.envпадает внятно, а не собираетконфигурацию с пустыми значениями.
infra/airflow/Dockerfileиinfra/superset/Dockerfileзаписанылитералом;
ARG *_BASE_IMAGEи парные проверки вconfig-test.shсняты;голая
docker buildдля обоих работает.compose.yamlпротив
.env.exampleпустая в обе стороны.«справочник, а не настройка» заменена.
make upс нуля,make smoke,make check-clickhouse,make check-servicesзелёные после копирования образца.Границы
версии не поднимать: это отдельная работа.
Dockerfileне трогать.вопрос только в том, где они объявлены.
Сначала прочитать
compose.yamlцеликом — инвентарь выше снят с него..env.example— 26 имён локальной настройки, все читаются Compose.generator/Dockerfile— образец правила, разобранный при #41.scripts/config-test.sh, строки 74–82 — проверки, которые снимаются..env.example.Проверка
make config-testdocker compose configбез.env— ожидается внятное падениеcp .env.example .env, затемmake upс нуляmake smoke,make check-clickhouse,make check-services