Конфигурация
Gotcha полностью настраивается переменными окружения с префиксом GOTCHA_. Ни одного конфиг-файла, ни одной настройки через веб-интерфейс для системных параметров — только переменные окружения. Их авторитетный источник — файл cmd/gotcha/config.go в исходном коде; этот документ — читаемое описание того же самого, сгруппированное по смыслу. Шаблон со всеми переменными и комментариями лежит в .env.example в корне репозитория.
Конвенция именования переменных
Числовая переменная несёт единицу измерения прямо в имени: _SECONDS, _DAYS, _HOURS, _BYTES, _PER_SEC, _PER_MIN (например GOTCHA_ESCALATION_INTERVAL_SECONDS, GOTCHA_EXPORT_RETENTION_HOURS, GOTCHA_DIST_RATE_PER_MIN). Голое число без единицы в имени неоднозначно — шестьдесят чего именно, секунд или минут? Для сроков хранения (retention) в имени называется ещё и вид данных, который отсекается (GOTCHA_EVENT_RETENTION_DAYS, GOTCHA_LOG_RETENTION_DAYS, GOTCHA_DEPLOY_RETENTION_DAYS), а не общий RETENTION_DAYS на всё сразу. Префикс переменной называет подсистему, а не продукт целиком: GOTCHA_AGENT_* — только процесс агента на хосте (gotcha-agent), отдельный бинарь; GOTCHA_DIST_* — раздачу инстансом бинарей агента (не сам агент); GOTCHA_PROBE_* — выносную пробу (--mode=probe). Невалидное значение любой переменной — отказ старта процесса, а не тихий откат к дефолту: опечатка в конфигурации обязана быть замечена оператором сразу, а не спустя недели молчаливо неверного поведения.
Конвенцию единиц измерения проверяет тест internal/guards/env_example_test.go: подозрительна ЛЮБАЯ переменная, прочитанная в cmd/gotcha/config.go или internal/agent/config.go как голое число (intNum/num) без нужного суффикса в имени — гейт валит её, если она не перечислена явно в закрытом списке unitlessCounters того же теста (счётчики штук вроде лимитов, конкурентности и порта, у которых единицы измерения нет и быть не может). Добавление новой строки в этот список — заметная в код-ревью правка, а не тихий обход конвенции.
Отдельно от значения — само ИМЯ переменной тоже проверяется при старте. GOTCHA_*, которую не читает ни cmd/gotcha, ни internal/agent (реестр известных имён — internal/envcontract/known.go, объединение серверных и агентских переменных: агент штатно ставится на тот же хост, что и сервер, с общим .env), отказывает старту с подсказкой ближайшего известного имени (расстояние Левенштейна не больше двух) — опечатка вроде GOTCHA_HSTS_ENABLE (без D) больше не проходит молча с дефолтом. Исключение — префиксы GOTCHA_COMPOSE_* и GOTCHA_BUILD_*: их читает сам Docker Compose (подстановка ${...}) или Makefile (build-args образа), ни один Go-процесс их не читает, и в реестр известных имён они не входят.
Как задать переменные окружения в Docker Compose
Два равнозначных способа:
Способ 1 — файл .env рядом с docker-compose.yml (рекомендуется, самый простой). Docker Compose читает его автоматически:
# в папке gotcha/
nano .env
GOTCHA_SECRET_KEY=случайная-строка-из-openssl-rand
GOTCHA_BASE_URL=https://gotcha.example.com
GOTCHA_SMTP_HOST=smtp.yandex.ru
GOTCHA_SMTP_PORT=465
GOTCHA_SMTP_USER=noreply@example.com
GOTCHA_SMTP_PASSWORD=пароль-приложения
GOTCHA_SMTP_FROM=noreply@example.com
Применить изменения:
docker compose up -d
(команда пересоздаёт контейнер gotcha с новыми переменными; postgres/clickhouse не трогает, если их переменные не менялись).
Способ 2 — блок environment: прямо в docker-compose.yml. Если вы не хотите заводить .env, можно прописать переменные прямо в compose-файле, в секции сервиса gotcha:
services:
gotcha:
# ...
environment:
GOTCHA_PG_DSN: postgres://gotcha:gotcha@postgres:5432/gotcha?sslmode=disable
GOTCHA_CH_DSN: clickhouse://gotcha:gotcha@clickhouse:9000/gotcha
GOTCHA_BASE_URL: ${GOTCHA_BASE_URL:-http://localhost:59080}
GOTCHA_SECRET_KEY: ${GOTCHA_SECRET_KEY:-insecure-dev-secret}
GOTCHA_SMTP_HOST: smtp.yandex.ru
${VAR:-default} — это подстановка Docker Compose: «взять значение VAR из окружения/.env, а если не задано — использовать значение после :-». В штатном docker-compose.yml репозитория уже используется этот приём для GOTCHA_BASE_URL и GOTCHA_SECRET_KEY, так что для этих двух переменных обычно достаточно способа 1 (просто создать .env), ничего не редактируя в самом compose-файле.
После любого изменения переменных выполните docker compose up -d, чтобы применить их — Docker Compose сам обнаружит, что конфигурация контейнера изменилась, и пересоздаст его.
Core (основные)
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_LISTEN_ADDR | :8080 | Адрес и порт, который слушает HTTP-сервер внутри контейнера. Как правило, менять не нужно — наружу порт пробрасывается через docker-compose.yml/GOTCHA_COMPOSE_PORT (см. Установку), а не через эту переменную. |
GOTCHA_BASE_URL | http://localhost:8080 | Публичный адрес вашего инстанса — то, как до него реально добираются пользователи и SDK. Используется для построения DSN проектов, ссылок в письмах-приглашениях и ссылок на инциденты в алертах (Telegram/webhook/email). Должен точно совпадать со схемой+хостом+портом, по которым инстанс реально доступен. Если значение не localhost/127.0.0.1, приложение в режимах web, all, ingest и uptime (везде, кроме probe) требует не-дефолтный GOTCHA_SECRET_KEY — см. раздел Security ниже. Если значение не начинается с https:// и не локальное — в лог пишется предупреждение (сессионные cookie идут открытым текстом). |
GOMEMLIMIT | (вычисляется из cgroup) | Стандартная (без префикса GOTCHA_) переменная самого Go-рантайма — потолок кучи. Оставленная незаданной, читается напрямую internal/memlimit, который в контейнере сам выводит её из потолка cgroup (см. «Переменные только для Compose» ниже, GOTCHA_COMPOSE_MEM_LIMIT); задавайте вручную только на bare metal без cgroup или чтобы переопределить выведенное значение. |
Database (база данных)
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_PG_DSN | postgres://gotcha:gotcha@localhost:5432/gotcha?sslmode=disable | Строка подключения к PostgreSQL — хранит организации, проекты, пользователей, правила алертов, инциденты. В штатном docker-compose.yml уже выставлено postgres://gotcha:gotcha@postgres:5432/gotcha?sslmode=disable (имя хоста postgres — это имя сервиса в docker-сети). Менять нужно, только если вы используете внешнюю/собственную БД вместо контейнера из compose. Значение обрезается по краям; строка из одних пробелов — отказ старта (а не тихий откат на дефолтный localhost-DSN). Разбираемость DSN (URL-форма или keyword/value-форма, обе законны) проверяется на старте — опечатка отказывает запуск сразу, а не на первом подключении к БД. |
GOTCHA_CH_DSN | clickhouse://localhost:9000/gotcha | Строка подключения к ClickHouse — хранит события, спаны трейсов, метрики, профили, результаты аптайм-проверок. В штатном compose — clickhouse://gotcha:gotcha@clickhouse:9000/gotcha. Менять по тем же причинам, что и GOTCHA_PG_DSN. Тот же тримминг, тот же отказ старта на пробельном значении и та же проверка разбираемости на старте. |
Переменные только для compose (контейнеры баз)
Эти четыре — переменные подстановки Docker Compose, а не конфигурация процесса gotcha: приложение их не читает. Compose подставляет их в настройки контейнеров баз и в DSN выше.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_COMPOSE_PG_PASSWORD | gotcha | Пароль пользователя gotcha в PostgreSQL. Подставляется и в контейнер postgres (POSTGRES_PASSWORD), и в GOTCHA_PG_DSN приложения. Символы, требующие URL-экранирования (@ / : # %), использовать нельзя — значение попадает в DSN-URL как есть. |
GOTCHA_COMPOSE_CH_PASSWORD | gotcha | Пароль пользователя gotcha в ClickHouse. Та же механика и то же ограничение на символы, что у GOTCHA_COMPOSE_PG_PASSWORD. |
GOTCHA_COMPOSE_PG_MEM_LIMIT | 512m | Потолок памяти контейнера postgres. На сервере с запасом — поднять. |
GOTCHA_COMPOSE_CH_MEM_LIMIT | 2g | Потолок памяти контейнера clickhouse. Без cgroup-лимита ClickHouse считает своими 90% памяти хоста — именно потолок делает его бюджет памяти реальным. |
Смена пароля базы на живой установке. POSTGRES_PASSWORD/CLICKHOUSE_PASSWORD действуют только при первичной инициализации тома — на живой установке смена одной переменной запирает приложение перед базой, которая ждёт старый пароль. Порядок важен:
- Сменить пароль в самой базе:
docker compose exec postgres psql -U gotcha -d gotcha -c "ALTER USER gotcha WITH PASSWORD 'новый-пароль'" docker compose exec clickhouse clickhouse-client --user gotcha --password 'старый-пароль' -q "ALTER USER gotcha IDENTIFIED BY 'новый-пароль'" - Задать
GOTCHA_COMPOSE_PG_PASSWORD/GOTCHA_COMPOSE_CH_PASSWORDв.env. docker compose up -d— контейнер приложения пересоздаётся с новым DSN.
Переменные только для Compose (контейнер приложения)
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_COMPOSE_MEM_LIMIT | 1g | Потолок памяти контейнера gotcha. Приложение читает лимит из cgroup и само выставляет потолок кучи в 80% от него, поэтому достаточно поднять потолок — GOMEMLIMIT руками задавать не нужно. |
GOTCHA_COMPOSE_NET_MTU | 1500 | MTU сети контейнеров. Средство от одной конкретной поломки, описанной ниже; само по себе расхождение MTU — не повод сюда лезть. |
GOTCHA_COMPOSE_BIND | 127.0.0.1 | Адрес хоста, на который публикуется порт приложения. По умолчанию — только loopback: снаружи сервера порт недоступен, пока вы явно не зададите 0.0.0.0 (см. Установку). |
GOTCHA_COMPOSE_PORT | 59080 | Порт хоста, на который публикуется контейнер приложения (порт 8080 внутри контейнера не меняется). Смените, если 59080 на хосте уже занят другим сервисом. |
Переменные только для сборки (build-args Makefile)
Эти три — тоже переменные подстановки, но не Docker Compose, а Makefile: он передаёт их дальше в docker compose build как build-args образа (DOCKER_BUILD_ENV, см. Dockerfile). Ни один процесс gotcha их не читает; сборка make задаёт их сама (git describe/коммит/дата) — эти переменные нужны, только если вы собираете образ через docker compose build напрямую, в обход make.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_BUILD_VERSION | dev | Версия, которую бинарник печатает в /healthz и логе старта. make задаёт её сама из git describe --tags. |
GOTCHA_BUILD_COMMIT | (пусто) | Хеш коммита, зашиваемый в бинарник тем же путём. |
GOTCHA_BUILD_DATE | (пусто) | Дата сборки, зашиваемая в бинарник тем же путём. |
Отталкиваться от симптома, а не от чисел. Docker даёт сети контейнеров MTU 1500, не глядя на аплинк хоста, а у VPS за туннелем (GRE, VXLAN, OpenVZ) он сплошь и рядом 1450. Само по себе расхождение встречается повсеместно, и большинство установок живут с ним, ничего не замечая.
Но безвредно оно только в одну сторону. Исходящие пакеты чинит своё же ядро: узкое звено — собственный интерфейс хоста, ядро сообщает об этом контейнеру, тот понижает MTU маршрута. Входящие зависят от удалённой стороны: она шлёт сегменты того размера, который контейнер объявил при установке соединения (MSS = MTU − 40, то есть 1460 вместо 1410), и уменьшит их, только если получит ICMP «fragmentation needed» от узла на пути. Дойдёт ли этот ICMP — не ваша сторона и не ваш контроль. Если его режут, отправитель продолжает слать по 1460 байт, и они пропадают.
Отсюда все признаки этой поломки:
- мелкие обмены идут, крупные пропадают: TCP устанавливается, приветствие SMTP
220приходит, а TLS-хендшейк — первый крупный обмен — виснет по таймауту; - разные адресаты ведут себя по-разному: до одного хоста TLS проходит, до другого нет, потому что ICMP режут не везде;
- может работать, а потом перестать: ядро держит выученный PMTU в кэше маршрута около десяти минут (
net.ipv4.route.mtu_expires), и пока запись жива, всё в порядке — после протухания симптом возвращается сам; - с хоста то же самое работает всегда: там интерфейс 1450, и MSS сразу объявляется 1410, никакого ICMP не требуется.
Последний пункт — главная ловушка при диагностике. Проверять надо изнутри контейнера, а не с хоста:
docker compose exec gotcha wget -q -O /dev/null https://api.github.com/ && echo ok || echo fail
Если отсюда TLS виснет, а с хоста openssl s_client -starttls smtp -connect <ваш-smtp>:587 проходит целиком — дело именно в MTU.
Этим же путём идёт всё исходящее — почта, вебхуки, OAuth и HTTP-проверки аптайма, — поэтому, когда это всё-таки случается, наблюдаемый сайт может числиться недоступным из-за MTU контейнера, который за ним наблюдает.
Проверка на хосте:
ip -o link show
Если у внешнего интерфейса (ens3, eth0) MTU меньше 1500, у docker0 — 1500, и при этом наблюдается описанный таймаут, задайте GOTCHA_COMPOSE_NET_MTU равным значению интерфейса и поднимите стек заново. Тогда контейнер объявляет MSS, который путь заведомо вывозит, и доставка перестаёт зависеть от чужого ICMP:
docker compose down && docker compose up -d
Именно down, а не один up -d: смена значения требует пересоздания сети, и если делать это под работающими контейнерами, встроенный DNS Docker остаётся с прежними записями — сервисы перестают находить друг друга по имени (lookup postgres on 127.0.0.11:53: server misbehaving), пока стек не поднимут целиком.
Если доставка не восстановилась — дело было не в MTU: верните значение обратно и разбирайтесь с достижимостью (Оповещения проводят по шагам).
Email / SMTP
Используется для писем-приглашений и email-канала алертов. Пока GOTCHA_SMTP_HOST пуст — отправка почты выключена целиком (в логах будет предупреждение GOTCHA_SMTP_HOST is not set, email alert channels are disabled), при этом остальная функциональность работает нормально.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_SMTP_HOST | (пусто) | Адрес SMTP-сервера, например smtp.yandex.ru. Пока пусто — почта выключена. |
GOTCHA_SMTP_PORT | 587 | Порт SMTP. 587 (STARTTLS) — обычный выбор; некоторые провайдеры используют 465 (SMTPS). Допустимый диапазон — 1..65535; значение вне него — отказ старта, а не отложенная ошибка при первой отправке письма. |
GOTCHA_SMTP_USER | (пусто) | Логин для авторизации на SMTP-сервере. |
GOTCHA_SMTP_PASSWORD | (пусто) | Пароль. Для сервисов вроде Яндекс/Gmail обычно нужен не пароль от аккаунта, а отдельный «пароль приложения». |
GOTCHA_SMTP_FROM | (пусто) | Адрес отправителя в заголовке From: писем. |
Telegram
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_TELEGRAM_API_BASE | (пусто — https://api.telegram.org) | Базовый адрес Bot API. Задайте, если инстанс не достаёт до api.telegram.org: фильтрация трафика по пути, закрытый исход из периметра, собственный сервер telegram-bot-api. Требуется абсолютный http(s)-адрес без запроса и фрагмента — отправитель дописывает /bot{token}/sendMessage; невалидное значение останавливает запуск, а не превращается в таймаут на каждой доставке. |
Исходящий прокси для Telegram задаётся стандартными переменными HTTPS_PROXY/HTTP_PROXY/NO_PROXY. На webhook-каналы, OAuth и проверки аптайма он не распространяется: они намеренно ходят к цели напрямую, потому что SSRF-фильтр решает по фактическому адресу соединения, а прокси унёс бы это решение за пределы инстанса. Диагностика Telegram — в разделе Оповещения.
Retention (хранение данных ClickHouse)
Сколько дней ClickHouse хранит данные каждого типа, прежде чем удалить старые записи. Меньше — меньше места на диске, больше — глубже история для расследований.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_EVENT_RETENTION_DAYS | 90 | Хранение событий (ошибок), транзакций и Web Vitals, а также описывающих их сводных записей в PostgreSQL: групп ошибок, групп производительности и регрессий производительности (см. Приватность). Прочие сводные записи живут сроком СВОЕЙ телеметрии: инциденты метрик — GOTCHA_METRIC_RETENTION_DAYS, регрессии профилей — GOTCHA_PROFILE_RETENTION_DAYS, закрытые инциденты аптайма — GOTCHA_INCIDENT_RETENTION_DAYS. Этим же сроком живут результаты проверок аптайма (check_results), поэтому значение меньше 90 укорачивает и историю публичной статус-страницы: она показывает не больше этого числа дней (обычно — 90). 0 — хранить бессрочно: TTL в ClickHouse снимается, по возрасту ничего не удаляется. |
GOTCHA_SPAN_RETENTION_DAYS | 30 | Хранение спанов трейсов (детали внутри транзакций). 0 — хранить бессрочно. |
GOTCHA_METRIC_RETENTION_DAYS | 30 | Хранение точек метрик (принятых по OTLP). 0 — хранить бессрочно. |
GOTCHA_PROFILE_RETENTION_DAYS | 7 | Хранение сэмплов профилирования (самые тяжёлые по объёму данные, поэтому дефолт короче остальных). 0 — хранить бессрочно. |
GOTCHA_LOG_RETENTION_DAYS | 14 | Хранение структурных логов (принятых по OTLP или NDJSON — см. Логи). Логи объёмнее событий, поэтому дефолт короче. 0 — хранить бессрочно. |
GOTCHA_INCIDENT_RETENTION_DAYS | 90 | Хранение ЗАКРЫТЫХ инцидентов аптайма в PostgreSQL. Своя переменная, а не общая с событиями: у инцидента аптайма нет собственной телеметрии в ClickHouse (результаты проверок живут отдельным сроком), зато его показывает публичная статус-страница, обещающая историю за девяносто дней. Открытые инциденты не удаляются никогда. 0 — хранить закрытые инциденты бессрочно. |
GOTCHA_DEPLOY_RETENTION_DAYS | 90 | Хранение маркеров выкладок в PostgreSQL. Своя переменная, а не общая с событиями: история выкладок — отдельная ось, не привязанная к телеметрии в ClickHouse, а таблицу пишет публичный ключ приёма (CI шлёт деплой тем же DSN) вне квоты, поэтому граница обязательна. 0 — хранить выкладки бессрочно. |
GOTCHA_PROJECT_PURGE_RECONCILE_HOURS | 24 | Как часто искать в ClickHouse телеметрию проектов, которых больше нет, и ставить её в очередь на удаление. Удаление проекта ставит заявку само — той же транзакцией, что удаляет строку, — а сверка нужна на случай, когда заявки не появилось вовсе: падение до фиксации транзакции, ручная правка строк, данные, оставшиеся от прежних версий. 0 выключает сверку: это нужно установке, где в тот же ClickHouse пишет что-то помимо gotcha. |
GOTCHA_OUTBOX_RETENTION_DAYS | 7 | Хранение записей об уже доставленных/провалившихся уведомлениях (email/webhook/Telegram) в PostgreSQL. Значение специально небольшое: это рабочая очередь, а не архив: она живёт в PostgreSQL и растёт вместе с числом уведомлений. Минимум 1 — 0 отвергается на старте. |
Изменение retention применяется на следующем старте приложения (значение используется, чтобы выставить TTL на таблицах ClickHouse) — задним числом уже удалённые данные не восстановятся.
Quotas & edition (квоты и редакция)
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_EDITION | oss | oss или saas, без учёта регистра (OSS/SaaS тоже принимаются). Определяет дефолт для квот ниже: в oss все дефолты = 0 (безлимит), в saas = 1 000 000 в месяц. Явно заданный GOTCHA_DEFAULT_*_QUOTA всегда перекрывает дефолт редакции. |
GOTCHA_DEFAULT_EVENT_QUOTA | 0 в oss | Дефолтная месячная квота на приём событий (ошибок) для новых организаций. 0 = безлимит. |
GOTCHA_DEFAULT_TRANSACTION_QUOTA | 0 в oss | То же для транзакций (performance-трейсов). |
GOTCHA_DEFAULT_METRIC_QUOTA | 0 в oss | То же для точек метрик. |
GOTCHA_DEFAULT_PROFILE_QUOTA | 0 в oss | То же для профилей. |
GOTCHA_DEFAULT_LOG_QUOTA | 0 в oss | То же для логов. |
GOTCHA_MAX_EVENT_BYTES | 1048576 (1 МиБ) | Максимальный размер одного принимаемого события в байтах. Событие крупнее — отклоняется. |
GOTCHA_INGEST_RATE_PER_SEC | 500 | Per-DSN лимит приёма: запросов в секунду на проект (токен-бакет, burst = 2×лимит). Проверяется после аутентификации DSN и до квот; сверх лимита API отвечает 429 с коротким Retry-After. 0 отключает лимит. |
GOTCHA_MAX_WRITER_BUFFER_BYTES | авто (см. ниже) | Байтовый потолок КАЖДОГО буфера писателя в ClickHouse (события, спаны, метрики, профили, логи). Буферы растут, пока ClickHouse недоступен, — так телеметрия не теряется на коротком сбое; потолок ограничивает эту плату. Заданное здесь число всегда побеждает авто-поведение. Результаты аптайм-проверок буферизуются отдельно и ограничены по числу строк (10000), а не этой переменной. Незаданная переменная включает авто-поведение; явные 0 и отрицательное число — ошибка конфигурации, отказ старта. |
GOTCHA_MAX_INGEST_QUEUE_BYTES | 67108864 (64 МиБ) | Байтовый потолок очереди приёма — в дополнение к её ёмкости в 1000 задач. Одно событие несёт до четырёх сырых JSON-блоков по 256 КиБ, то есть до мегабайта, и без этого потолка очередь могла удерживать порядка гигабайта. При исчерпании событие отбрасывается со счётчиком gotcha_pipeline_dropped_tasks_total; текущий объём виден в gotcha_pipeline_queue_bytes. Незаданная переменная берёт дефолт выше; явные 0 и отрицательное число — ошибка конфигурации, отказ старта. |
Авто-дефолт GOTCHA_MAX_WRITER_BUFFER_BYTES: если переменная не задана, потолок каждого буфера-писателя выводится из обнаруженного потолка кучи (того же 80%-от-GOTCHA_COMPOSE_MEM_LIMIT потолка, описанного выше в «Переменные только для Compose»), а не берётся flat-константой пакета (256 МиБ). Буферов-«единиц» шесть (событие, спаны-транзакций и спаны-детей у трейсинга — два независимых буфера одного писателя, метрики, профили, логи); авто-дефолт делит на них 60% потолка кучи, оставляя 40% на всё остальное (HTTP-приём, парсер JSON, клиент PostgreSQL, сам рантайм). На дефолтном docker-compose.yml (mem_limit: 1g, потолок кучи ≈ 819 МиБ) это даёт около 82 МиБ на буфер — вместо flat 256 МиБ, которые суммарно (1.5 ГиБ) превышали бы потолок кучи и на длительном простое ClickHouse могли привести к OOM ядра. Если потолок кучи вывести не из чего (bare-metal без cgroup и без GOMEMLIMIT) — поведение прежнее, flat 256 МиБ на буфер. Явно заданный GOTCHA_MAX_WRITER_BUFFER_BYTES всегда побеждает авто-дефолт — в том числе для стеснённых профилей (docker-compose.small.yml продолжает задавать 24 МиБ явно).
Когда обязательно менять квоты: значения 0 (безлимит) в oss-редакции — это сознательный выбор для приватного self-hosted инстанса, где DSN не утекает наружу. Если DSN проекта попадает в публично доступный код (например, во фронтенд-JS вашего сайта), кто угодно может слать на него события неограниченно — это и вектор злоупотребления, и риск исчерпать диск ClickHouse. В таком случае задайте реальные числа, например:
GOTCHA_DEFAULT_EVENT_QUOTA=100000
GOTCHA_DEFAULT_TRANSACTION_QUOTA=50000
(Это дефолт для новых организаций; квоту существующей организации можно изменить в её настройках в веб-интерфейсе.)
Privacy / scrubbing (приватность)
Серверная очистка персональных данных перед сохранением — включена по умолчанию.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_SCRUB_IP | true | Зануляет IP-адрес пользователя, о котором сообщило событие, перед сохранением. |
GOTCHA_SCRUB_EMAIL | true | Зануляет email пользователя, о котором сообщило событие, перед сохранением. |
GOTCHA_SCRUB_DENY_KEYS | встроенный список (password,passwd,pwd,pass,token,secret,authorization,auth,cookie,api_key,apikey,access_token,refresh_token,session,credit_card,card_number,cvv) | Список ключей (через запятую, без учёта регистра), значения которых маскируются в тегах/контекстах/стек-трейсах/данных спанов. Переменная дополняет встроенный список, а не заменяет его: добавить свой ключ (например, internal_user_id) можно одним значением, не перечисляя стандартные. Убрать конкретный встроенный ключ — точным именем через GOTCHA_SCRUB_KEEP_KEYS. |
GOTCHA_SCRUB_KEEP_KEYS | пусто | Точные имена-исключения из денилиста (через запятую). Матч намеренно fail-closed: имя маскируется, если содержит слово из денилиста, поэтому author (содержит auth) и tokenizer (содержит token) по умолчанию маскируются. Недо-маскирование — это утечка ПДн, а избыточное стоит лишь потерянного отладочного поля, и эта настройка его возвращает: GOTCHA_SCRUB_KEEP_KEYS=author,tokenizer. |
GOTCHA_SCRUB_FREETEXT | false | Дополнительно маскирует email-адреса, встреченные в свободном тексте (сообщение об ошибке, значение исключения, описание спана). Выключено по умолчанию сознательно: наивная маскировка может испортить SQL-запросы или URL в тексте ошибки. Маскируются только email, не телефоны и не другие виды ПДн. |
Ограничители и оценщики
Потолки, защищающие инстанс от лавины, и период фоновых оценщиков. Ограничивают РАБОТУ, а не хранение — поэтому вынесены из «Хранения» и «Квот», где стояли раньше.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_NOTIFY_CONCURRENCY | 4 | Сколько уведомлений доставляется одновременно. Один медленный канал (мёртвый вебхук ждёт до 30 секунд) не задерживает остальные. |
GOTCHA_ALERT_BUDGET_WINDOW_SECONDS | 3600 | Окно пер-проектного потолка уведомлений. |
GOTCHA_ALERT_BUDGET_LIMIT | 50 | Сколько уведомлений проект может отправить за это окно. Троттлинг правил ключуется парой (issue, правило), а у нового issue строки троттлинга нет — поэтому отправитель с уникальным fingerprint на каждое событие получал уведомление на каждое событие. Подавленное не теряется: после закрытия окна уходит сводка «подавлено ещё N». 0 выключает потолок целиком. |
GOTCHA_CARDINALITY_LIMIT | 10000 | Потолок РАЗЛИЧНЫХ значений открытых полей (имя транзакции, окружение, имя метрики, сервис, операция спана) на проект за окно. Значения сверх потолка не отбрасываются, а группируются под <cardinality-limit>; на затронутой странице показывается, по какому полю сработал потолок, и примеры сгруппированных значений. Причина почти всегда — идентификатор, попавший в имя, см. Кардинальность. 0 снимает ограничение. |
GOTCHA_CARDINALITY_WINDOW_SECONDS | 3600 | Окно, после которого набор различённых значений начинается заново — проект, починивший имена, возвращается к нормальной работе сам. |
GOTCHA_EVALUATORS_ENABLED | по режиму | Запускать ли периодические циклы: регрессии производительности, правила по метрикам, регрессии профилей, встроенные пороги хостов (диск/память/нагрузка/тишина), SLO burn-rate (slo.Evaluator) и планировщик эскалаций (escalation.Scheduler) — всего шесть. По умолчанию они идут с режимами uptime и all, хотя к аптайму отношения не имеют. При раздельном развёртывании web+ingest (аптайм не используется) правило по метрике, SLO-алерт и эскалация выглядят включёнными и не вычисляются никогда — включите переменную ровно на одной реплике. При старте в режиме без оценщиков в лог пишется предупреждение. |
GOTCHA_METRIC_EVAL_INTERVAL_SECONDS | 60 | Как часто (в секундах) проверяются пороговые правила алертов по метрикам. |
GOTCHA_PROFILE_EVAL_INTERVAL_SECONDS | 300 | Как часто (в секундах) запускается детектор регрессий профилирования. |
GOTCHA_HOST_EVAL_INTERVAL_SECONDS | 60 | Как часто (в секундах) фоновый оценщик пересчитывает встроенные пороги хостов (диск/память/нагрузка/тишина) и открывает/закрывает их инциденты, см. Хосты. Минимум — 1 секунда. Понижать имеет смысл только на маленьком парке: каждый тик — это запрос за последними точками по всем хостам проекта. |
GOTCHA_SLO_EVAL_INTERVAL_SECONDS | 120 | Как часто (в секундах) фоновый оценщик пересчитывает burn rate по SLO на быстром/медленном окнах и открывает/закрывает инциденты сжигания бюджета. Минимум — 1 секунда. SLO живут на окнах в дни, поэтому такт медленнее, чем у оценщиков метрик/хостов, достаточен. |
GOTCHA_ESCALATION_INTERVAL_SECONDS | 60 | Как часто (в секундах) планировщик эскалаций проверяет открытые неподтверждённые инциденты и продвигает лесенку на очередную ступень. Минимум — 1 секунда. Гейтится тем же GOTCHA_EVALUATORS_ENABLED, что и пять циклов выше. |
GOTCHA_DEPENDENCY_SETTLE_SECONDS | 300 | Грейс схлопывания гонки при падении родителя в графе подавления шторма: сколько ждать, прежде чем отправить уведомление или эскалировать зависимый узел, у которого задекларирован родитель. |
Наблюдаемость и логи
Детализация и формат логов самого инстанса.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_LOGGING_LEVEL | info | Детализация логов: debug, info, warn (алиас warning) или error, без учёта регистра. Поднимите до debug, чтобы получить больше подробностей во время инцидента, не пересобирая образ. Нераспознанное значение — отказ старта, а не тихий откат к info: опечатку в конфигурации логов (например, trace) нужно заметить сразу, а не искать в момент, когда детализации не хватает в разгар инцидента. |
GOTCHA_LOGGING_FORMAT | text | Формат логов: text или json, без учёта регистра. json удобнее, когда логи уезжают в Loki/ELK. Нераспознанное значение — отказ старта. |
Security (безопасность)
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_SECRET_KEY | insecure-dev-secret | Ключ подписи сессионных и OAuth state-cookie, а также мастер-ключ шифрования at-rest (SSO client secret, токены каналов, заголовки мониторов). Дефолт публичен (он в исходном коде) — оставлять его на реальном сервере значит разрешить угон аккаунта через OAuth. На не-localhost GOTCHA_BASE_URL приложение отказывается стартовать в режимах web, all, ingest и uptime (везде, кроме probe), пока не задан свой ключ, и требует, чтобы он был не короче 32 байт (слишком короткий ключ — слабая подпись). Сгенерировать: openssl rand -hex 32. Для нестандартного dev-окружения обе проверки снимает GOTCHA_SECRET_KEY_ALLOW_INSECURE=1. Значение обрезается по краям — "ключ " и "ключ" дают один и тот же итоговый ключ, случайный пробел при копировании не меняет шифрование; строка из одних пробелов — отказ старта, а не тихий откат на публичный дефолт. Подробности — в Установке, шаг 5. Менять ключ на работающем инстансе — только по процедуре ротации, см. «Приватность и 152-ФЗ». |
GOTCHA_SECRET_KEY_PREV | (пусто) | Предыдущий мастер-ключ на время ротации GOTCHA_SECRET_KEY — задаётся вместе с новым GOTCHA_SECRET_KEY на время перехода, затем убирается. Пока задан, приложение расшифровывает и им, и текущим ключом, а шифрует только текущим. В отличие от GOTCHA_SECRET_KEY, значение читается дословно, без обрезки пробелов по краям — чтобы ротация работала и для ключа, который хранился с хвостовым пробелом (тримминг превратил бы его в другой ключ и заблокировал бы расшифровку). Отсутствие тримминга не означает вседозволенность: значение из одних пробелов — та же ошибка гигиены, что и у GOTCHA_SECRET_KEY/GOTCHA_PG_DSN/GOTCHA_CH_DSN (скорее всего, случайный пробел при копировании, а не осознанный «ключ из пробелов»), и отказывает старт независимо от режима, а не тихо становится «настоящим» prev-ключом. Приложение отказывается стартовать при бессмысленной паре ключей: GOTCHA_SECRET_KEY_PREV равен текущему GOTCHA_SECRET_KEY, любой из них равен дефолтному dev-ключу при заданном GOTCHA_SECRET_KEY_PREV. GOTCHA_SECRET_KEY_ALLOW_INSECURE=1 эти проверки не снимает — это не про стойкость ключа, а про конфиг, который физически не может сделать то, что от него ждут. Процедура ротации — в «Приватность и 152-ФЗ». |
GOTCHA_TRUSTED_PROXIES | (пусто) | Список через запятую: CIDR (10.0.0.0/8) и/или голые IP (192.168.1.5, трактуется как /32 или /128) доверенных обратных прокси. За прокси (рекомендуемая топология установки) укажите здесь адрес прокси — тогда пер-IP лимитер логина ключуется по реальному IP клиента из X-Forwarded-For, а не по адресу прокси; иначе все попытки входа выглядят пришедшими с прокси и лимитер не различает клиентов. Невалидные записи — ошибка старта, а не тихий пропуск. |
GOTCHA_SECRET_KEY_ALLOW_INSECURE | false | Аварийный обход проверки выше — позволяет стартовать с дефолтным ключом даже на не-localhost адресе. Только для нестандартных dev-стендов, никогда не используйте в реальной эксплуатации. Значение разбирается на каждом старте безусловно, независимо от того, достаточно ли стойкий GOTCHA_SECRET_KEY: нераспознанное значение (не 1/0/true/false/yes/no/on/off) — отказ старта, а не тихий пропуск опечатки. |
GOTCHA_REGISTRATION_MODE | invite | Режим самостоятельной регистрации (без учёта регистра значения): open — открыта всем; invite — аккаунт заводится только по действующему приглашению (по паролю или через провайдера); closed — новых аккаунтов не появляется вообще, даже по действующему приглашению. В этом и разница: при closed приглашённый упрётся в «регистрация закрыта», и пригласить кого-то извне станет нельзя — приглашения работают только для тех, у кого аккаунт уже есть. Первый пользователь на чистом инстансе регистрируется всегда, независимо от настройки (bootstrap инстанс-админа). |
GOTCHA_HSTS_ENABLED | true | Отправляет ли само приложение Strict-Transport-Security — и только на ответах, отданных по https:// GOTCHA_BASE_URL (см. Усиление установки); на голом HTTP-деплое заголовок не уходит независимо от этой настройки. Настраивайте HSTS РОВНО в одном месте — либо на обратном прокси, либо в приложении, никогда в обоих сразу. Выключение НЕ снимает пин у браузеров: тот, что уже получил max-age=31536000, год будет отказываться от голого HTTP независимо от этой настройки — приложение лишь перестаёт отправлять заголовок, до кэша браузера ему не дотянуться. Единственный способ реально снять пин — реально отправленный max-age=0 (см. GOTCHA_HSTS_MAX_AGE_SECONDS ниже), для чего эта настройка обязана оставаться true. |
GOTCHA_HSTS_MAX_AGE_SECONDS | 31536000 | Сколько секунд браузеру велено помнить требование HTTPS; дефолт — год. 0 — законное, осознанное значение, а не «выключено»: это единственный способ реально отозвать ранее отправленный пин — отправить GOTCHA_HSTS_ENABLED=true с этим значением 0, чтобы снять пин у браузеров, уже закэшировавших заголовок, а затем поднять значение обратно, когда авария позади. Если ещё выставлен GOTCHA_HSTS_PRELOAD=true, сначала выключите его (GOTCHA_HSTS_PRELOAD=false) — проверка preload ниже требует max-age не меньше года, поэтому 0 вместе с PRELOAD=true — отказ старта; полный порядок аварийного отката — в Усилении установки. Отрицательное значение — всегда опечатка, приложение отказывается стартовать. |
GOTCHA_HSTS_INCLUDE_SUBDOMAINS | false | Расширяет требование HTTPS на все поддомены хоста из GOTCHA_BASE_URL, а не только на сам хост. По умолчанию выключено намеренно: инстанс Gotcha часто живёт на поддомене более крупного домена (например, gotcha.example.com), и включение заставило бы требовать HTTPS от КАЖДОГО другого сервиса на example.com — сервисов, на которые этот инстанс никак не влияет и которые могут быть даже не готовы к HTTPS. Включайте только если контролируете (или проверили HTTPS на) весь родительский домен целиком. |
GOTCHA_HSTS_PRELOAD | false | Помечает инстанс кандидатом на списки предзагрузки HSTS браузеров (зашиты прямо в браузер, минуя даже первый небезопасный запрос) — сама подача заявки описана в Усилении установки, эта переменная её не выполняет. Билет в один конец: как только домен зашит в релиз браузера, снять его оттуда можно месяцами, и это касается пользователей, которые вообще никогда не заходили на инстанс. Требует GOTCHA_HSTS_INCLUDE_SUBDOMAINS=true и GOTCHA_HSTS_MAX_AGE_SECONDS не меньше года — иначе приложение отказывается стартовать, потому что список предзагрузки всё равно отклонит заголовок без любого из двух условий, а оператор будет считать, что заявка уже подана. |
GOTCHA_LOCALE | ru | Язык исходящих уведомлений (аптайм, регрессии, производительность) в email/Telegram/webhook: ru или en, без учёта регистра. У получателя вне веб-интерфейса нет своей локали, поэтому язык выбирает оператор — один на инстанс. Веб-интерфейс настройка не трогает: там каждый выбирает язык сам. |
GOTCHA_SSRF_ALLOW_PRIVATE | false | Разрешить аптайм-проверкам и исходящим webhook-алертам обращаться к приватным/loopback/link-local адресам (например, 192.168.x.x, 127.0.0.1, 169.254.x.x). Держите false на любом инстансе, доступном нескольким пользователям/организациям — иначе один пользователь может завести «аптайм-проверку» или вебхук, который на самом деле сканирует вашу внутреннюю сеть (SSRF). |
GOTCHA_SSRF_ALLOW_PRIVATE_UPTIME | наследует GOTCHA_SSRF_ALLOW_PRIVATE | Разрешить аптайм-проверкам ходить на приватные/loopback-адреса. Обычно единственный, который нужен: мониторить внутренний сервис — рутина, а цель задаёт админ организации. |
GOTCHA_SSRF_ALLOW_PRIVATE_WEBHOOK | наследует GOTCHA_SSRF_ALLOW_PRIVATE | Разрешить вебхукам алертов ходить на приватные адреса. Рискованнее: до 1 КБ ответа цели показывается на странице доставок, что превращает вебхук в читалку внутренних сервисов. |
GOTCHA_SSRF_ALLOW_PRIVATE_OIDC | наследует GOTCHA_SSRF_ALLOW_PRIVATE | Разрешить запросам OIDC (discovery/token) ходить на приватные адреса — нужно для внутреннего IdP. Рискованнее всего: client secret уходит на token_endpoint, взятый из discovery-документа. |
GOTCHA_SSRF_ALLOW_PRIVATE_TELEGRAM | наследует GOTCHA_SSRF_ALLOW_PRIVATE | Разрешить запросам к Telegram Bot API ходить на приватные адреса — нужно только когда GOTCHA_TELEGRAM_API_BASE указывает на внутренний прокси/бридж Telegram. Наименее опасный из четырёх: базовый URL задаёт оператор инстанса, а не арендатор, поэтому его нельзя превратить в пользовательский SSRF, как цель аптайма или вебхука. |
GOTCHA_AUTO_MIGRATE_ENABLED | true | Применять миграции схемы БД автоматически при старте. false — миграции нужно применить отдельным шагом заранее, иначе приложение откажется стартовать на устаревшей схеме. Подробности и когда это нужно — в Обновлении. |
GOTCHA_EXTERNAL_CHANNEL_DETAILS_ENABLED | false | Отправлять ли текст ошибки (заголовок/culprit/тело) во внешние каналы алертов (Telegram/webhook). false — отправляется только обезличенная ссылка обратно на инстанс, без текста ошибки (текст ошибки может содержать персональные данные, которые вы не хотите, чтобы покидали периметр). |
GOTCHA_TRUSTED_RECIPIENTS | пусто | Домены и хосты вашего контура через запятую: почта на этих доменах и вебхуки на этих хостах получают детали события даже при выключенном GOTCHA_EXTERNAL_CHANNEL_DETAILS_ENABLED. Совпадение по границе доменной метки (corp.example покрывает mail.corp.example, но не evilcorp.example). Хост инстанса из GOTCHA_BASE_URL и адреса внутренней сети доверенные всегда и без настройки. См. Приватность и 152-ФЗ. |
Флаг командной строки
--migrate-onlyприменяет схему и завершает процесс, не поднимая ни одного компонента: init-job для развёртываний сGOTCHA_AUTO_MIGRATE_ENABLED=false. См. Обновление.
Режимы процесса: что запускает каждый --mode=
Роль процесса задаётся флагом бинаря --mode= (не переменной окружения): all по умолчанию — так работает штатный docker-compose.yml; web, ingest и uptime — для раздельного развёртывания на несколько реплик; probe — выносная проба (см. ниже). Таблица показывает, какие компоненты поднимает каждый режим. Все четыре режима с базой держат HTTP-слушатель со служебными ручками (/healthz, /readyz, /version, /metrics, см. Мониторинг самого gotcha) и на старте выполняют бэкфилл секретов под текущий GOTCHA_SECRET_KEY.
| Компонент | web | ingest | uptime | all |
|---|---|---|---|---|
HTTP-приём телеметрии (/api/v1/*), писатели ClickHouse (события, спаны, метрики, профили, логи), детектор всплесков, учёт сигналов приёма | — | ✓ | — | ✓ |
| Интерфейс (все страницы, вход, SSO, API проб), джанитор сессий и просроченных приглашений | ✓ | — | — | ✓ |
Воркер и джанитор выгрузок (если каталог GOTCHA_EXPORT_DIR доступен на запись) | ✓ | — | — | ✓ |
| Планировщик аптайма (ставит проверки в очередь) | ✓ (с предупреждением в логе: проверки ставятся, но не выполняются) | — | ✓ | ✓ |
| Исполнитель аптайм-проверок и watchdog (heartbeat, напоминания) | — | — | ✓ | ✓ |
| Доставка уведомлений: воркер outbox, дайджест подавленных, джанитор outbox | ✓ | ✓ | ✓ | ✓ |
| Оценщики: регрессии производительности, правила по метрикам, регрессии профилей, пороги хостов, SLO burn rate; планировщик эскалаций; джаниторы инцидентов и групп инцидентов | только с GOTCHA_EVALUATORS_ENABLED=true | только с GOTCHA_EVALUATORS_ENABLED=true | ✓ | ✓ |
| Джанитор сущностей PostgreSQL по срокам хранения (проблемы, инциденты, регрессии, хосты, маркеры деплоя) | ✓ | ✓ | ✓ | ✓ |
| Очистка ClickHouse от телеметрии удалённых проектов | ✓ | ✓ | ✓ | ✓ |
Отсюда два следствия для раздельного развёртывания. Во-первых, web — не «только интерфейс»: он доставляет уведомления и подчищает базу наравне с остальными, поэтому запись notify outbox janitor в его логе — норма, а не признак перепутанного режима. Во-вторых, без реплики uptime или all оценщики не работают нигде — поднимите их явно через GOTCHA_EVALUATORS_ENABLED=true ровно на одной реплике (см. «Ограничители и оценщики»).
Uptime & probe (аптайм и выносные пробы)
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_UPTIME_CONCURRENCY | 50 | Сколько аптайм-проверок выполняется одновременно (в режимах uptime/all, а также выносной пробой в режиме probe). |
GOTCHA_UPTIME_LOCAL_REGION | local | Имя встроенного локального региона аптайм-проверок — то, что видно в интерфейсе при выборе региона монитора. |
GOTCHA_PROBE_KEY | (пусто) | Только для --mode=probe: bearer-токен, которым выносная проба аутентифицируется к центральному инстансу. Обязателен в этом режиме. |
GOTCHA_PROBE_SERVER_URL | (пусто) | Только для --mode=probe: базовый URL центрального инстанса Gotcha, к которому подключается проба. Обязателен в этом режиме, должен быть абсолютным http(s)-адресом без запроса и фрагмента; хвостовая косая срезается сама. Задан в другом режиме — переменную никто не читает, в лог пишется предупреждение, старт продолжается. |
Режим --mode=probe — это отдельный процесс, разворачиваемый в другом регионе/дата-центре: он не открывает ни PostgreSQL, ни ClickHouse, только ходит наружу к центральному инстансу по HTTP.
Agent distribution (раздача бинарей агента)
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_DIST_DIR | /opt/gotcha/agent-dist | Каталог с install.sh и собранными бинарями gotcha-agent (gotcha-agent-linux-amd64, gotcha-agent-linux-arm64, SHA256SUMS), которые инстанс раздаёт по GET /install.sh и GET /agent/{file} — именно с этого пути тянет команда установки агента (см. Хосты). Дефолт совпадает с путём, куда Docker-сборка кладёт бинари в образ, — на штатном docker-compose-проде задавать переменную не нужно. Каталога по этому пути физически нет в dev-режиме (go run без Docker) или на сборке не из Docker-образа — тогда оба маршрута отвечают 404 с подсказкой, а не падают. Значение задаёт только каталог раздачи: сам скрипт install.sh встроен в бинарь gotcha и одинаков для всех инстансов и версий продукта. |
GOTCHA_DIST_RATE_PER_MIN | 120 | Порог per-IP лимитера GET /agent/{file} (загрузка бинаря агента и SHA256SUMS). Одна установка/обновление стоит 2 запроса, поэтому дефолт даёт ~60 хостов в минуту с одного IP — с запасом для массовой раскатки (Ansible/Terraform) или обновления парка за одним NAT/egress-адресом. Поднимите значение, если за одним IP стоит парк больше. 0 (и отрицательное значение) снимает лимит полностью — GET /agent/{file} перестаёт резаться по частоте, как и у *_RETENTION_DAYS, где 0 означает «без границы». |
Выгрузки (export)
Подробности фичи и ограничений — в Выгрузках.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_EXPORT_DIR | /var/lib/gotcha/exports | Каталог на диске инстанса, куда воркер пишет файлы выгрузок. В штатном docker-compose.yml это именованный том exportdata, переживающий пересоздание контейнера. Если каталог не удаётся создать на старте (нет прав, занято не-каталогом) или он существует, но недоступен на запись этому процессу (например, точку монтирования свежего тома создал сам Docker и она досталась не тому владельцу) — приложение не падает: раздел выгрузок молча выключается — сама страница /projects/{id}/exports при этом по-прежнему отвечает 200 с пояснением, что раздел недоступен на этом инстансе, а не пустой таблицей; 404 получают только постановка/скачивание/удаление заявки (см. Выгрузки). В лог пишется предупреждение. Каталог создаётся с правами 0700 (в нём лежат ПДн из событий/ошибок, как и в файлах внутри — они уже 0600): создание не меняет режим уже существующего каталога, поэтому на инсталляциях, где каталог достался с более широкими правами (например 0755 от Docker при монтировании тома, см. выше), права нужно поправить вручную — chmod 0700. |
GOTCHA_EXPORT_RETENTION_HOURS | 168 | Через сколько часов после завершения заявки готовый файл удаляется фоновым джанитором (заявка помечается «истекла»). 168 — семь суток. Строка заявки в истории живёт дольше: не меньше 30 суток от завершения, подробнее в Выгрузках. В отличие от GOTCHA_DIST_RATE_PER_MIN выше, 0 и отрицательное значение здесь НЕ означают «без ограничения» — файл считался бы истёкшим сразу после сборки. Приложение отказывается стартовать с таким значением. |
GOTCHA_EXPORT_MAX_ROWS | 200000 | Потолок строк одной выгрузки: при достижении заявка помечается «обрезана» (Truncated), сборка останавливается детерминированно, а не молча отдаёт неполный файл без пометки. 0 и отрицательное значение здесь НЕ означают «без лимита» (не та же конвенция, что у GOTCHA_DIST_RATE_PER_MIN/*_RETENTION_DAYS) — приложение отказывается стартовать. |
GOTCHA_EXPORT_MAX_BYTES | 268435456 | Потолок размера файла одной выгрузки в байтах (256 МиБ). Тот же смысл, что у GOTCHA_EXPORT_MAX_ROWS, но по объёму, а не по числу строк; та же оговорка про 0 и отрицательные значения. |
GOTCHA_EXPORT_DISK_BUDGET_BYTES | 5368709120 | Суммарный бюджет каталога GOTCHA_EXPORT_DIR в байтах (5 ГиБ). Проверяется до начала записи файла, а не частично записанный файл. Переполнение — ВРЕМЕННЫЙ отказ новой заявки (до 3 попыток, см. Выгрузки) — самоустраняется первым же проходом джанитора, который освобождает диск от истёкших файлов. 0 и отрицательное значение здесь НЕ означают «без бюджета» — «занято ≥ бюджет» истинно уже на пустом каталоге, и КАЖДАЯ заявка отказывала бы без единой попытки; приложение отказывается стартовать с таким значением. |
OAuth / SSO
Каждый провайдер входа включается независимо. Если включить провайдер, не задав его обязательные секреты — приложение откажется стартовать.
| Переменная | По умолчанию | Описание |
|---|---|---|
GOTCHA_OIDC_ENABLED | false | Включает вход через произвольный OIDC-провайдер (Keycloak, Authentik, Google Workspace и т.п.). Требует GOTCHA_OIDC_ISSUER, GOTCHA_OIDC_CLIENT_ID, GOTCHA_OIDC_CLIENT_SECRET. |
GOTCHA_OIDC_ISSUER | (пусто) | URL издателя (issuer) OIDC-провайдера. |
GOTCHA_OIDC_CLIENT_ID | (пусто) | Идентификатор приложения, зарегистрированного у провайдера. |
GOTCHA_OIDC_CLIENT_SECRET | (пусто) | Секрет того же приложения. |
GOTCHA_OIDC_SCOPES | openid email profile | Полный список scope через запятую (тот же разделитель, что у остальных списочных переменных этого документа), который уходит провайдеру — перед отправкой запятая нормализуется в пробел, как того требует сам протокол. Заданное значение заменяет список по умолчанию, а не дополняет его, поэтому всегда включайте openid и email: без них в ID-токене не будет ни субъекта, ни адреса, и вход перестанет работать. Чтобы запросить дополнительный scope, перечислите его вместе со стандартными: openid,email,profile,groups. Пустые элементы (лишняя запятая) отбрасываются; значение из одних запятых и пробелов трактуется как незаданное — уходит дефолт. |
GOTCHA_OIDC_DISPLAY_NAME | (пусто) | Отображаемое имя кнопки входа («Войти через …») в интерфейсе. |
GOTCHA_YANDEX_ENABLED | false | Включает вход через Yandex ID. Требует GOTCHA_YANDEX_CLIENT_ID/GOTCHA_YANDEX_CLIENT_SECRET. |
GOTCHA_YANDEX_CLIENT_ID | (пусто) | Идентификатор приложения, зарегистрированного в Yandex ID. |
GOTCHA_YANDEX_CLIENT_SECRET | (пусто) | Секрет того же приложения. |
GOTCHA_VK_ENABLED | false | Включает вход через VK ID. Требует GOTCHA_VK_CLIENT_ID/GOTCHA_VK_CLIENT_SECRET. |
GOTCHA_VK_CLIENT_ID | (пусто) | Идентификатор приложения, зарегистрированного в VK ID. |
GOTCHA_VK_CLIENT_SECRET | (пусто) | Секрет того же приложения. |
Пошаговая настройка каждого провайдера — в SSO.
Что дальше
- Установка — с чего начать на чистом сервере.
- Резервное копирование и восстановление.
- Обновление.
- SSO.