Node.js 20 в статусе EOL: как обновить API, SSR и фоновые обработчики без остановки заказов
На сервере всё ещё работает Node.js 20, поэтому кажется, что обновление можно отложить. Но ветка уже находится в статусе EOL: штатных обновлений безопасности для неё больше нет.
Найдите все процессы Node.js, включая фоновые задания и сборку. Выберите поддерживаемую ветку по совместимости приложения, а не только по номеру версии. На тесте проведите заказ через API, SSR, очередь и вебхук; перед рабочим переключением подготовьте откат и наблюдение за ошибками.
Содержание 24 разделов
Что делать бизнесу, у которого JS-сервисы всё ещё работают на 20-й ветке
Статья адресована владельцам JavaScript-сервисов, интернет-магазинов, API и внутренних приложений, которые используют Node.js 20 в production и должны решить, когда и как переходить на поддерживаемую версию.
По официальному списку Node.js, ветка 20 (Iron) достигла EOL 24 марта 2026 года, а не 30 апреля. Приложение от этого не выключается, но штатная поддержка и исправления безопасности для ветки закончились. План обновления должен охватывать API, SSR, фоновые обработчики, зависимости и сценарий отката.
Почему «работает же» — не аргумент
Если сервис на Node.js 20 продолжает принимать заказы, это не доказательство его безопасности. Проверьте, где запущен этот runtime, какие пакеты и нативные модули от него зависят, и сравните критичные операции на поддерживаемой версии. Особенно внимательно тестируйте очереди, повторы и вебхуки: ошибка в них не всегда видна на главной странице.
Что именно означает статус EOL
«Last updated» ≠ дата окончания поддержки
На странице релизов nodejs.org у каждой ветки есть колонка «Last updated» — это дата последнего фактического патч-релиза (для 20-й ветки — 24 марта 2026, версия 20.20.2) [1]. Это не то же самое, что дата окончания планового жизненного цикла. Плановая дата EOL для чётных LTS-веток фиксируется заранее и почти всегда приходится на 30 апреля соответствующего года — независимо от того, когда вышел последний патч [5][8]. Для Node.js 20 это 30 апреля 2026 года — дата, подтверждённая как на самой странице EOL nodejs.org, так и в независимых обзорах жизненного цикла [2][4][8].
Путаница здесь встречается системно: команды смотрят на «Last updated», видят недавнюю дату и делают вывод, что версия ещё «свежая», хотя статус уже — EOL. Важно помнить и обратное: сам факт истечения поддержки не означает, что приложение немедленно остановится или сломается — риск накапливается постепенно, а не проявляется одномоментно.
Что произойдёт, если ничего не делать
Ничего резкого. Ни один процесс не остановится сам. Но начнут накапливаться параллельные риски:
- Отсутствие патчей безопасности. Новые уязвимости в V8, npm, OpenSSL или ядре Node для 20-й ветки закрываться не будут [2].
- Разрыв с экосистемой. Библиотеки и SDK постепенно поднимают минимальную требуемую версию Node в поле
engines. Например, Salesforce CLI объявил переход на требование Node ≥ 22, ссылаясь напрямую на то, что 18-я и 20-я ветки достигли EOL [7]. - Проблемы с комплаенсом. Многие отраслевые аудиты и внутренние политики безопасности прямо запрещают использование неподдерживаемых рантаймов [2].
- Поломка сборки при обновлении базовых Docker-образов. Официальные образы
node:20со временем перестают обновляться.
Три коммерческих партнёра OpenJS Foundation — HeroDevs, NodeSource и TuxCare — предлагают платный бэкпорт патчей безопасности для EOL-версий Node.js как временную меру для тех, кто пока не может обновиться [2][4]. Это явно позиционируется как временное решение, а не альтернатива апгрейду [2].
Как найти все места, где реально работает Node.js

Production-серверы и менеджеры процессов
- Проверить фактическую версию на каждом сервере:
node -vилиprocess.versionвнутри приложения [8], а не то, что записано в документации проекта. - Посмотреть конфигурацию менеджеров процессов (PM2, systemd unit-файлы, supervisord) — там часто зашит абсолютный путь к бинарнику конкретной версии Node.
- Проверить serverless-функции отдельно: у облачных провайдеров рантаймы Node деактивируются поэтапно (например, у AWS Lambda процесс отключения версии идёт в три фазы — сначала прекращаются патчи безопасности, затем блокируется создание новых функций, затем блокируется обновление существующих) [3]. Дедлайны в облаке могут не совпадать с датой EOL самого Node.js и наступать раньше.
Dockerfile и базовые образы
- Найти все
FROM node:...во всех Dockerfile’ах, включая базовые образы для CI-раннеров и локальной разработки. - Проверить теги на плавающие версии (
node:20,node:lts) — они могли незаметно «уехать» на другую минорную версию внутри 20-й ветки, но мажорная ветка всё равно останется EOL. - Проверить
.dockerignore: если в образ копируются локально собранныеnode_modulesс уже скомпилированными нативными модулями, при смене версии Node внутри контейнера они могут не совпасть по ABI с рантаймом контейнера — ошибка проявится не на этапе сборки, а только при первом обращении к модулю в проде [14].
CI/CD и сборочные пайплайны
- Проверить файлы
.nvmrc,.node-version, полеenginesвpackage.json, а также явное указание версии Node в конфигурации CI (GitHub Actionssetup-node, GitLab CI образы, Jenkins-агенты). - Частая ситуация: production обновили, а CI продолжает собирать и тестировать сборку на старой версии — тесты «зелёные», но не на той версии, что реально в проде.
SSR-фреймворки и edge-рантаймы
- Отдельно проверить окружение серверного рендеринга: Next.js, Nuxt, Remix и подобные фреймворки нередко запускаются в отдельном контейнере или на отдельной платформе со своей версией Node, которая может отличаться от версии основного API.
- Проверить, поддерживает ли используемая мажорная версия фреймворка целевую версию Node.
Что проверить перед выбором целевой версии
Зависимости, lock-файлы, поле engines
Нужно пройтись по package-lock.json/yarn.lock/pnpm-lock.yaml и проверить:
- какие пакеты в
enginesявно ограничивают диапазон поддерживаемых версий Node; - какие мажорные версии критичных зависимостей (ORM, HTTP-клиент, очереди, драйвер БД) требуются для совместимости с целевой веткой;
- нет ли пакетов, которые официально прекратили поддержку и требуют замены параллельно с апгрейдом Node.
Нативные расширения и ABI
Каждая мажорная версия Node меняет ABI (NODE_MODULE_VERSION), и любой пакет с нативным кодом — .node-бинарником, собранным через node-gyp, — должен быть пересобран или переустановлен под новую версию, иначе процесс упадёт при попытке его загрузить [9][11].
Если зависимости используют Node-API (N-API), а не устаревшие V8-заголовки напрямую, гарантируется ABI-стабильность между мажорными версиями [9][13]. Но на практике многие пакеты смешивают N-API с прямыми обращениями к V8 или NAN — такие места являются самыми частыми источниками поломок при мажорном апгрейде [10]. Практическая проверка:
- Полная чистая переустановка (
rm -rf node_modules && npm ci) на целевой версии Node. - Явный
npm rebuildдля пакетов с нативным кодом. - Прогон полного тестового набора именно на целевой версии.
Если критичная зависимость с нативным кодом ещё не публикует сборки под самую свежую LTS, разумный компромисс — временно остановиться на предыдущей поддерживаемой ветке (сейчас это Node 22, Maintenance LTS), а не оставаться на уже снятой с поддержки версии [12].
Поддержка фреймворков и облачных платформ
Отдельно стоит свериться с матрицей поддерживаемых версий Node у используемого хостинга, PaaS-платформы, менеджера очередей и мониторинга.
Как выбрать поддерживаемую ветку
Правило Node.js: только чётные версии получают статус LTS, каждая живёт около 30 месяцев (12 месяцев Active LTS + 18 месяцев Maintenance), переход в Maintenance-фазу обычно происходит в октябре, а окончание поддержки — в апреле [5][8]. На момент выхода этой статьи:

- Node.js 22 — Maintenance LTS, поддержка до 30 апреля 2027 года;
- Node.js 24 — Active LTS, поддержка до 30 апреля 2028 года.
Официальная позиция мейнтейнеров проекта — переходить сразу на Node.js 24, если это возможно, а не на 22: 22-я ветка уже находится в фазе сопровождения и получит статус EOL на год раньше [6]. Единственная разумная причина выбрать 22 вместо 24 — если критичная зависимость (чаще всего с нативным кодом) ещё не поддерживает 24-ю ветку [12]. Ориентироваться нужно не на «самую новую версию» саму по себе, а на пересечение: какая версия одновременно является LTS, поддерживается всеми критичными зависимостями и совместима с используемыми SSR-фреймворками и облачной платформой.
Российская специфика: ФСТЭК, БДУ и управление уязвимостями
Сам по себе рантайм Node.js — открытое ПО с международной разработкой, и вопрос о включении в реестр отечественного ПО к нему не применяется. Российская специфика лежит в другой плоскости — в требованиях к управлению уязвимостями.
Если компания — субъект критической информационной инфраструктуры (187-ФЗ) или проходит аудит на соответствие требованиям ФСТЭК России, снятый с поддержки рантайм рассматривается как открытая, неустранимая уязвимость. Банк данных угроз безопасности информации (БДУ) ФСТЭК ведёт публичный реестр уязвимостей программного и программно-аппаратного обеспечения, сопоставленный с международными идентификаторами CVE [15]. Приказ ФСТЭК №235 закрепляет требования к защите объектов КИИ, а бесплатный сканер ScanOVAL, работающий на OVAL-контенте с портала bdu.fstec.ru, выявляет использование программных компонентов с известными уязвимостями на конкретном хосте [16]. Коммерческие сканеры вроде MaxPatrol VM выполняют ту же задачу в масштабе инфраструктуры и рассчитывают SLA на устранение по каждой найденной уязвимости [17].
Фоновые обработчики: очереди, вебхуки, повторы после сбоя
Апгрейд версии Node чаще всего тестируют на HTTP-слое и забывают про фоновые процессы — а именно там чаще всего теряются данные при деплое [20].
Node.js по умолчанию завершается по SIGTERM немедленно, без дренажа: активные HTTP-запросы обрываются, открытые транзакции БД откатываются, а обработчики очередей теряют состояние выполняемой задачи [18]. Для очередей на базе BullMQ, например, у воркера есть метод, который прекращает забор новых задач и ждёт завершения текущей — но только в пределах заданного тайм-аута; просроченные задачи уходят в очередь повторов согласно настроенной политике retry [18][21].
Что стоит проверить отдельно от основного API до переключения на новую версию Node:
- Обработка вебхуков. Идемпотентность обработчика (повторная доставка того же вебхука не должна создавать дубликат заказа), корректная проверка подписи запроса, поведение при таймауте на стороне партнёра.
- Фоновые очереди. Поведение при штатном перезапуске воркера: завершаются ли активные задачи, не теряются ли задачи, стоящие в очереди на момент остановки.
- Повторы после сбоя. Политика retry (число попыток, экспоненциальная задержка, дедупликация) должна быть протестирована именно на целевой версии Node — как отдельный сценарий с реальным поднятием и штатной остановкой процесса.
Как сравнить SSR и критичные API на тестовом трафике

- Теневой (shadow) трафик. Копия части реальных запросов направляется одновременно на старую и новую версию, ответы сравниваются, но пользователю возвращается только ответ от текущей продакшн-версии.
- Canary-развёртывание. Небольшая доля реального трафика (обычно 1–10%) обслуживается новой версией, при этом отслеживаются метрики ошибок, задержки и потребления памяти в динамике — некоторые проблемы проявляются не сразу, а спустя 10–15 минут работы [19].
- Сравнение SSR отдельно от API. Для серверного рендеринга важно сверять не только код ответа, но и содержимое отрендеренной страницы — расхождения проявляются именно в HTML-выводе, а не в статус-кодах.
- Health-check, который не врёт. Эндпоинт проверки готовности должен реально проверять соединение с базой данных и внешними зависимостями, а не просто отвечать
200 OK[19].
Поэтапное переключение и откат
- Rolling-обновление. Инстансы заменяются по одному или небольшими группами, каждый корректно дренируется по SIGTERM перед остановкой [19].
- Blue-green. Полный параллельный набор инстансов на новой версии разворачивается рядом со старым, трафик переключается разом после проверки, откат — мгновенное переключение обратно.
- Canary. Постепенное увеличение доли трафика на новую версию с постоянным мониторингом метрик; при отклонениях — автоматический или ручной откат.
Общее условие для любой из стратегий — заранее готовый и проверенный путь отката: старая версия должна оставаться развёрнутой или мгновенно разворачиваемой, пока новая версия не отработала в проде достаточное время без инцидентов [19].

Практический результат: план обновления
Ниже — сводный чек-лист, который можно использовать как рабочий план миграции.
Зависимости и окружение для проверки:
- версия Node в
.nvmrc/.node-version/enginesвpackage.json; - версия Node во всех
Dockerfile(production, CI-раннеры, локальная разработка); - версия Node в конфигурации CI/CD (GitHub Actions, GitLab CI, Jenkins);
- версия Node в менеджерах процессов (PM2, systemd) и на serverless-платформе;
- пакеты с нативным кодом (native addons) — список и статус поддержки целевой версии;
- пакеты, чей
enginesограничивает диапазон версий Node; - версия используемого SSR-фреймворка и его минимальные требования к Node;
- драйверы БД, очередей и observability-агентов — совместимость с целевой веткой.
Регрессионные тесты перед переключением:
- полный набор unit- и интеграционных тестов на целевой версии после
npm ciиnpm rebuild; - отдельный прогон обработчиков очередей: штатная остановка воркера, поведение retry-политики, потеря/сохранение задач в очереди;
- отдельный прогон обработки вебхуков: идемпотентность при повторной доставке, проверка подписи, поведение при таймауте;
- сравнение SSR-вывода (HTML) между старой и новой версией на одинаковых входных данных;
- сравнение критичных API-эндпоинтов на теневом или canary-трафике по кодам ответа, задержке и содержимому;
- проверка health-check эндпоинта на реальную готовность (БД, кэш, внешние зависимости), а не формальный
200 OK; - тест пути отката: возврат на предыдущую версию/образ без потери данных.
Ограничения, ошибки и риски
- Путаница дат. Смотреть только на «Last updated» в таблице релизов и делать вывод о свежести версии — самая частая ошибка при аудите [1].
- Тестирование только HTTP-слоя. Фоновые обработчики, очереди и cron-задачи почти всегда тестируются менее тщательно, чем API [20].
- Забытые нативные зависимости. ABI-несовместимость нативных модулей проявляется не на этапе сборки, а в рантайме [10][14].
- Рассинхронизация версий между окружениями. Локальная машина, CI и production используют разные версии Node из-за отсутствия зафиксированной версии в
.nvmrc/engines. - Слепое обновление до самой новой версии. Node.js прямо предупреждает, что для продакшна должны использоваться только Active LTS или Maintenance LTS релизы [1].
- Отсутствие плана отката. Переключение без заранее протестированного пути назад — это ставка, а не инженерное решение [19].
Как выбрать между готовым решением и разработкой
Для большинства случаев обновление версии Node — это плановая инженерная задача, которую штатная команда разработки в состоянии закрыть самостоятельно: инвентаризация, проверка зависимостей, тестирование и поэтапный деплой не требуют внешней разработки как таковой. Внешняя экспертиза становится оправданной, если:
- в проекте много нативных зависимостей неясного происхождения, и непонятно, какие из них вообще активно поддерживаются;
- фоновая обработка (очереди, интеграции с внешними системами, вебхуки) реализована годами разными людьми без единого стандарта graceful shutdown;
- требуется параллельно провести технический аудит инфраструктуры для внутреннего комплаенса или подготовки к проверке по требованиям информационной безопасности.
Вывод
Node.js 20 достиг статуса EOL 30 апреля 2026 года, и это не аварийная ситуация, а плановая точка, которую бизнес должен был заложить в roadmap заранее [1][2]. Риск не в том, что приложение остановится само — окончание поддержки не означает немедленного прекращения работы, — а в том, что каждый день на EOL-версии увеличивает разрыв с экосистемой и накапливает неустранимые уязвимости. Практический путь: сначала найти все реальные точки использования Node.js — от Dockerfile до SSR-контейнера, — затем проверить зависимости и особенно нативные модули на ABI-совместимость, выбрать целевую LTS-ветку с учётом всего стека, отдельно протестировать фоновые обработчики и вебхуки, и только после сравнения на тестовом трафике переключать production поэтапно с готовым путём отката.
Источники
[1] nodejs.org — Node.js Releases — https://nodejs.org/en/about/previous-releases
[2] nodejs.org — End-Of-Life (EOL) — https://nodejs.org/en/about/eol
[3] cloudquery.io — AWS Lambda Node.js 20 EOL: Upgrade to Node.js 22 — https://www.cloudquery.io/blog/aws-lambda-nodejs-20-eol
[4] tuxcare.com — Node.js End-of-Life: Dates, Risks & What to Do Next — https://tuxcare.com/blog/node-eol/
[5] dev.to — Node.js End-of-Life Dates - Official EOL Schedule — https://dev.to/endoflifeai/nodejs-end-of-life-dates-official-eol-schedule-for-every-version-6do
[6] herodevs.com — Node.js v20 Is Reaching End of Life — https://www.herodevs.com/blog-posts/node-js-v20-is-reaching-end-of-life
[7] github.com — forcedotcom/cli, issue #3603 — https://github.com/forcedotcom/cli/issues/3603
[8] endoflife.ai — Node.js End of Life: Every Version's Dates — https://endoflife.ai/article-nodejs-eol
[9] nodejs.org — Node-API — https://nodejs.org/api/n-api.html
[10] medium.com — N-API Addons Break in 8 Sneaky Ways on Node Upgrades — https://medium.com/@Quaxel/n-api-addons-break-in-8-sneaky-ways-on-node-upgrades-b7419a289179
[11] versions.dev — Upgrade to Node.js 20 LTS — breaking changes & migration guide — https://versions.dev/modernize/node/upgrade-to-node-20
[12] versions.dev — Upgrade to Node.js 24 LTS — breaking changes & migration guide — https://versions.dev/modernize/node/upgrade-to-node-24
[13] pkgpulse.com — node-gyp vs prebuild vs napi-rs: Native Addons 2026 — https://www.pkgpulse.com/guides/node-gyp-vs-prebuild-vs-napi-rs-native-nodejs-addons-2026
[14] zylos.ai — Native Module ABI Compatibility in Containerized Node.js Agent Runtimes — https://zylos.ai/research/2026-06-17-native-module-abi-containerized-node-agent-runtimes/
[15] bdu.fstec.ru — Раздел угроз безопасности информации — https://bdu.fstec.ru/threat-section
[16] credos.ru — ФСТЭК БДУ – реестр угроз безопасности информации — https://www.credos.ru/articles-info/fstek-bdu-reestr-ugroz-bezopasnosti-informatsii/
[17] sgrc.cyberosnova.ru — Методика управления уязвимостями ФСТЭК: руководство 2026 — https://sgrc.cyberosnova.ru/blog/metodika-upravleniya-uyazvimostyami-fstek/
[18] dev.to — Node.js Graceful Shutdown in Production — https://dev.to/axiom_agent/nodejs-graceful-shutdown-in-production-sigterm-in-flight-draining-and-zero-downtime-deploys-2a7h
[19] dev.to — Zero-Downtime Deployments in Node.js: Blue-Green, Rolling, and Canary Explained — https://dev.to/axiom_agent/zero-downtime-deployments-in-nodejs-blue-green-rolling-and-canary-explained-192k
[20] dev.to — Node.js 26 vs Node.js 24 LTS: should you upgrade now? — https://dev.to/aarav_chandel_bf81a1120b1/nodejs-26-vs-nodejs-24-lts-should-you-upgrade-now-3l83
[21] 1xapi.com — Node.js Graceful Shutdown: Zero-Downtime Guide 2026 — https://1xapi.com/blog/nodejs-graceful-shutdown-zero-downtime-deployments-2026