Что живёт в git, а что в .env: убрать параметризацию, которой нечего параметризовать #60

Closed
opened 2026-08-07 11:46:22 +03:00 by ddmitry · 0 comments
Owner

Цель

Убрать из 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
## Цель Убрать из `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`
ddmitry added the ready-for-human label 2026-08-07 11:46:33 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ddmitry/clickstream-data-platform#60