Почему на Modal слетают кастомные ноды после рестарта
На Modal кастомные ноды обычно исчезают после рестарта не потому, что ComfyUI «ломается», а потому что ручная установка меняет только текущий работающий контейнер.
На Modal кастомные ноды обычно исчезают после рестарта не потому, что ComfyUI «ломается», а потому что ручная установка меняет только текущий работающий контейнер. Как только среда перезапускается, Modal поднимает новый экземпляр из заранее собранного шаблона, и всё, чего в нём не было, просто не возвращается.
Рабочее решение простое: ноды, Python-зависимости и системные пакеты нужно фиксировать в template или image, а модели, кэши и тяжёлые файлы — хранить в постоянном хранилище. Тогда после перезапуска ComfyUI стартует в том же состоянии, а не как будто вы заходите в чистую сборку.
Именно поэтому запросы modal custom nodes reset, слетают ноды modal и comfyui modal restart обычно сводятся к одному сценарию: нода была установлена вручную через живой интерфейс или терминал, но не была включена в воспроизводимую конфигурацию проекта. Ниже разберём, что именно происходит внутри Modal, почему Manager здесь помогает лишь частично и как закрепить всё на уровне шаблона.
Содержание
- Что именно происходит при рестарте на Modal
- Почему установка через Manager не переживает рестарт
- Как закрепить ноды и зависимости в шаблоне
- Что хранить в Image, а что в Volume
- Чек-лист перед deploy
- Частые вопросы
Что именно происходит при рестарте на Modal
Если упростить, у вас есть четыре слоя: код шаблона, собранный image, постоянное хранилище и текущий живой контейнер. Пока вы ставите что-то руками внутри уже запущенного ComfyUI, вы меняете только последний слой. Это удобно для проверки, но такие изменения не становятся частью сборки автоматически.
Поэтому типичный сценарий выглядит так: вы открываете ComfyUI, через Manager доустанавливаете missing custom nodes, видите, что workflow ожил, радуетесь, а потом перезапускаете приложение или обновляете страницу — и красные блоки возвращаются. На самом деле новый контейнер просто стартует из той версии image, где этих нод никогда не было.
Именно здесь Modal сильно отличается от привычного ощущения «я один раз поставил пакет, и он лежит на сервере». В случае с шаблонным запуском важен не сам факт ручной установки, а то, описана ли она в коде развертывания. По этой же причине готовый template под конкретный сценарий нередко оказывается практичнее, чем пустой сервер с ручной настройкой. Если хотите шире посмотреть на этот подход, полезно сравнить его с материалом почему готовый template под конкретный workflow часто лучше, чем чистый server.
| Что вы сделали | Где это осталось | Переживёт ли рестарт |
| Поставили ноду вручную через Manager в запущенной сессии | Внутри текущего контейнера | Чаще всего нет |
| Добавили git clone и pip install в template | В image, который строится заново по коду | Да |
| Сохранили модели и кэши в Volume | В постоянном хранилище | Да |
| Скачали модель в локальную папку контейнера во время работы | Внутри текущего контейнера | Не гарантировано |
Есть ещё один важный нюанс. Некоторые пользователи замечают, что модели иногда «как будто остаются», а кастомные ноды — нет. Обычно это связано с тем, что веса моделей заранее вынесены в постоянное хранилище или вообще не требуют такого же сценария рестарта, как Python-модули и кастомный код ноды. Но логика для нод остаётся прежней: если репозиторий и зависимости не описаны в шаблоне, после нового старта они не считаются частью окружения.
Почему установка через Manager не переживает рестарт
ComfyUI-Manager полезен как диагностический инструмент: он помогает увидеть, каких нод не хватает, и быстро понять, чего не достаёт вашему workflow. Но на Modal он не должен быть финальной точкой настройки. Всё, что Manager сделал в живом контейнере, остаётся живым ровно до тех пор, пока жив сам контейнер.
Проблема становится заметнее из-за того, что многие кастомные ноды не просто кладут файлы в папку custom_nodes, а ещё тянут свои Python-зависимости, иногда системные библиотеки и дополнительные пакеты. Чтобы ComfyUI их увидел, нужен перезапуск backend-процесса. И вот в этот момент вы фактически просите Modal поднять окружение заново. Если нода не была внесена в template, новый старт происходит уже без неё.
Из практики это выглядит так: пользователь ставит ноду, жмёт restart, получает короткий успех, потом делает повторный запуск и снова видит UNKNOWN или отсутствующие классы. Часто кажется, что проблема в самом workflow, хотя реальная причина намного прозаичнее — установка не была закреплена на уровне сборки. Если у вас иногда возникают похожие сбои и по другим причинам, рядом по смыслу будет материал почему workflow может висеть, падать или работать через раз.
Отдельно стоит понимать, что путь к нодам сам по себе не решает задачу. Положить папку «куда надо» — это только часть дела. Важно, чтобы тот же набор файлов оказался доступен в каждом новом запуске, а зависимости ставились в той же версии. Для базового понимания структуры ComfyUI может пригодиться статья куда вообще ставить custom nodes и почему без них половина workflow мёртвая.
Как закрепить ноды и зависимости в шаблоне
Надёжная схема на Modal всегда одна и та же: сначала вы определяете окружение в коде, потом собираете его, и только после этого считаете установку завершённой. Иными словами, не «допиливаете» ComfyUI руками после запуска, а описываете всё, что ему понадобится, заранее.
Практически это выглядит так:
- соберите список всех кастомных нод, которые нужны конкретному workflow;
- проверьте, какие репозитории нужно клонировать и есть ли у них requirements.txt;
- добавьте установку Python-пакетов и системных зависимостей в код шаблона;
- зафиксируйте версии там, где это критично;
- только потом поднимайте ComfyUI и проверяйте workflow на чистом старте.
Ниже — упрощённый пример логики шаблона. Он не претендует на универсальность для любой ноды, но хорошо показывает сам принцип:
image = (
modal.Image.debian_slim(python_version="3.12")
.apt_install("git")
.uv_pip_install("нужные-python-пакеты")
.run_commands(
"git clone https://github.com/owner/custom-node /root/ComfyUI/custom_nodes/custom-node",
"cd /root/ComfyUI/custom_nodes/custom-node && pip install -r requirements.txt"
)
)
Смысл этого куска не в конкретных пакетах, а в подходе: всё важное описано до старта контейнера. Если вы пересобираете приложение, Modal разворачивает новую версию image, а не пытается вспомнить, что вы когда-то нажимали в интерфейсе. Тот же принцип стоит использовать и для workflow JSON: лучше держать его как часть контролируемой конфигурации, а не как случайный файл из браузерной сессии. В тему здесь статья что такое workflow JSON в ComfyUI и почему это не просто картинка с настройками.
Если вам нужно быстро проверить сборку, логичнее сначала прогнать её в режиме отладки, а уже потом публиковать постоянную версию. Это особенно полезно, когда вы ещё не уверены в списке зависимостей, путях к моделям или порядке запуска. По смыслу это хорошо рифмуется с разницей между serve и deploy в Modal: сначала дебаг и проверка, потом стабильный деплой.
Что важно закреплять сразу
- репозиторий каждой кастомной ноды;
- requirements.txt или список pip-зависимостей;
- системные пакеты, если нода их требует;
- пути к workflow и служебным конфигам;
- версии пакетов, если на них завязана совместимость.
Самая частая ошибка — собрать «почти рабочую» среду, а последний missing package поставить руками уже после старта. Формально кажется, что всё готово, но при следующем запуске именно эта мелочь и ломает граф.
Что хранить в Image, а что в Volume
Удобное правило такое: код и зависимости должны жить в image, а тяжёлые данные — в Volume. Тогда вы не смешиваете логику сборки со storage-слоем и не пытаетесь лечить архитектурную проблему случайными докачками в процессе работы.
Обычно в Image имеет смысл хранить
- сам ComfyUI и способ его запуска;
- репозитории кастомных нод;
- Python-пакеты и системные библиотеки;
- фиксированные конфиги, workflow-шаблоны и служебные файлы проекта.
Обычно в Volume имеет смысл хранить
- чекпойнты, LoRA и VAE;
- большие модели и кэш загрузок;
- выходные изображения и промежуточные результаты;
- данные, которые должны сохраняться между запусками.
Это разделение экономит время и деньги. Когда вы меняете только код ноды или список зависимостей, вы пересобираете image. Когда вы работаете с весами, не хочется скачивать их заново на каждый старт — для этого и нужен Volume. Но есть тонкость: если ваш процесс пишет что-то важное в Volume уже во время выполнения, это состояние должно действительно сохраняться и быть доступным следующему контейнеру. Иначе получится другая версия той же проблемы: данные как будто были, но новый экземпляр их не видит.
Отсюда практический вывод: кастомная нода — это часть окружения, а не «временный файл». Даже если сама нода ещё что-то скачивает или кэширует, её код и зависимости лучше фиксировать в image, а не держать надежду на случайно удачную сессию.
Чек-лист перед deploy
Перед публикацией шаблона удобно пройтись по короткому списку. Он экономит много времени, когда workflow уже вроде бы запускается, но после первого же перезапуска начинает разваливаться.
- На чистом старте workflow открывается без красных missing nodes.
- Ни одна обязательная нода не ставится вручную после запуска контейнера.
- Все репозитории нод и их зависимости прописаны в template.
- Модели, LoRA и кэши лежат в постоянном хранилище, если они должны переживать рестарт.
- Пути внутри workflow совпадают с теми, что реально существуют в контейнере.
- Вы отдельно проверили сценарий «остановить и запустить заново», а не только «обновить вкладку».
- После сборки вы тестируете не старый контейнер, а новую версию окружения.
- Только после этого переводите проект в deploy.
Если после такой проверки ноды всё равно исчезают, почти всегда остаётся одна из трёх причин: не все зависимости попали в шаблон, нужный репозиторий клонируется не туда, либо workflow ссылается на старые имена классов после обновления ноды. В этих случаях полезно сравнивать не только интерфейс, но и логи старта ComfyUI.
Частые вопросы
Почему после рестарта иногда пропадает только часть нод?
Потому что разные элементы живут в разных слоях. Что-то уже было в image, что-то хранится в Volume, а что-то вы добавили только в текущую сессию. На новом старте возвращается лишь то, что реально входит в воспроизводимую конфигурацию.
Можно ли вообще ставить ноды через Manager на Modal?
Да, как способ быстро понять, чего не хватает, это удобно. Но финальная фиксация должна происходить в template. Manager хорош для диагностики, а не как единственный механизм постоянной установки.
Нужно ли держать отдельный шаблон под каждый workflow?
Не всегда, но на практике это часто упрощает жизнь. Если workflows требуют разный набор нод и моделей, один «универсальный» шаблон быстро обрастает лишним и становится менее предсказуемым.
Что важнее проверить первым делом, если всё снова сломалось?
Сначала убедитесь, что нода действительно описана в шаблоне, а не была установлена вручную. Потом проверьте requirements, пути к папкам custom_nodes и совместимость самих версий. Обычно ошибка находится именно здесь.
Итог простой: на Modal слетают не «кастомные ноды вообще», а любые изменения, которые были сделаны только в живом контейнере и не закреплены в шаблоне. Если перенести установку в image, хранить данные в Volume и отделить этап проверки от этапа deploy, ComfyUI после рестарта будет подниматься в предсказуемом состоянии, а не как новая случайная сборка.