Compose pre_start Idempotency Risk Analyzer
Найти в шагах pre_start команды, небезопасные при повторном запуске после сбоя.
Как это работает
Секция pre_start в Docker Compose 5.3 не даёт никакой транзакционности между шагами: если второй шаг из трёх упадёт, первый не откатится, а при повторном docker compose up все шаги, включая уже успешно отработавший первый, запустятся заново с нуля. Если первый шаг — это INSERT без проверки на существование записи, второй запуск создаст дубликат, а не молча пропустит уже сделанную работу. Compose pre_start Idempotency Risk Analyzer online ищет в командах pre_start эвристические признаки неидемпотентных операций.
Идемпотентность здесь означает простую вещь: повторный запуск той же команды должен приводить к тому же результату, что и один запуск, а не накапливать побочные эффекты. INSERT INTO без ON CONFLICT или IF NOT EXISTS, mkdir без флага -p, миграции без явного трекинга уже применённых шагов — классические примеры операций, которые один раз отработают штатно, а при повторном запуске после сбоя другого шага дадут неожиданный результат.
Инструмент проходит по введённым командам pre_start и ищет паттерны, статистически связанные с неидемпотентным поведением: SQL-операции без защитных конструкций, файловые операции без флагов идемпотентности, и команды создания ресурсов без предварительной проверки существования — не как строгий гарантированный вердикт, а как список мест, которые стоит перепроверить вручную перед боевым использованием.
Частые вопросы
Может ли инструмент гарантированно определить, идемпотентна ли команда?
Нет, это эвристический анализ по распознаваемым паттернам в тексте команды, а не полноценный статический анализ семантики скрипта, окончательное решение об идемпотентности конкретной команды остаётся за тем, кто пишет и тестирует pre_start шаг.
Как сделать SQL INSERT идемпотентным на практике?
Самый частый подход — использовать ON CONFLICT DO NOTHING в PostgreSQL или INSERT OR IGNORE в SQLite, либо предварительную проверку через SELECT перед вставкой, чтобы повторный запуск того же запроса не создавал дубликат записи.
Что если pre_start шаг — это применение миграций через готовый инструмент вроде Alembic или Prisma Migrate?
Большинство современных инструментов миграций уже спроектированы идемпотентными по дизайну — они трекают, какие миграции уже применены, и пропускают их при повторном запуске, такие шаги обычно безопасны, инструмент их тоже пометит как низкий риск при распознавании известных команд.
Стоит ли вообще беспокоиться об идемпотентности, если pre_start обычно срабатывает успешно?
Именно редкость сбоя и делает это опасным — неидемпотентный шаг молча работает нормально месяцами, пока однажды не случится частичный сбой второго или третьего шага в цепочке, и тогда повторный запуск первого шага создаст проблему, которую тяжело диагностировать постфактум.