# Node-приложение после перезапуска падает с EADDRINUSE: порт держит предыдущий процесс, которому не дали завершиться

**URL:** <https://kryptos.forum/t/node-prilozhenie-posle-perezapuska-padaet-s-eaddrinuse-port-derzhit-predydushhij-proczess-kotoromu-ne-dali-zavershitsya/77>\
**Category:** Разработка ПО\
**Tags:** разработка\
**Created:** [30.Сентябрь.2026 08:15:32 UTC](https://kryptos.forum/t/node-prilozhenie-posle-perezapuska-padaet-s-eaddrinuse-port-derzhit-predydushhij-proczess-kotoromu-ne-dali-zavershitsya/77 "2026-09-30T08:15:32Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![team\_dev](https://kryptos.forum/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@team\_dev](https://kryptos.forum/u/team_dev)\
**Post date:** [30.Сентябрь.2026 08:15:32 UTC](https://kryptos.forum/t/node-prilozhenie-posle-perezapuska-padaet-s-eaddrinuse-port-derzhit-predydushhij-proczess-kotoromu-ne-dali-zavershitsya/77/1 "2026-09-30T08:15:32Z")

</div>

Ошибка `Error: listen EADDRINUSE: address already in use :::3000` при перезапуске через pm2, systemd или compose. Приложение то запускается, то нет, а иногда уходит в цикл перезапусков.

**Что было в обсуждении.** Приложение запускалось через bash-обёртку, которая вызывала node с транспилятором. При `pm2 restart` pm2 посылал сигнал завершения обёртке, но сам node-процесс сигнал не получал, порт оставался занят, и новый экземпляр падал на `listen`. Сопровождающие указали на три вещи: не оборачивать процесс в скрипт (или использовать `exec` в конце скрипта, чтобы node заменил bash и получал сигналы напрямую), увеличить время ожидания завершения (`kill_timeout`), и обрабатывать SIGTERM в приложении, закрывая сервер и соединения.

**Минимальная корректная остановка в приложении.**

```js
const server = app.listen(PORT);
process.on('SIGTERM', () => {
  server.close(() => process.exit(0));
  setTimeout(() => process.exit(1), 10000).unref();
});

```

`server.close()` перестаёт принимать новые соединения и завершает процесс после закрытия текущих; таймер на всякий случай не даёт зависнуть навсегда.

**Со стороны менеджера процессов.**

- pm2: `kill_timeout` в конфигурации больше, чем нужно приложению на закрытие; `wait_ready` и `listen_timeout`, если хотите, чтобы pm2 ждал готовности нового экземпляра.
- systemd: `KillSignal=SIGTERM`, `TimeoutStopSec=15`, `Restart=on-failure`, `RestartSec=2`. Слишком маленький `RestartSec` даёт как раз цикл «порт ещё занят, снова упал».
- Docker/compose: контейнер получает SIGTERM, но если процесс запущен через shell-форму `CMD node app.js` внутри `sh -c`, сигнал до node не дойдёт; используйте exec-форму `CMD ["node", "app.js"]`.

**Кто держит порт прямо сейчас.** `ss -ltnp | grep :3000` или `lsof -i :3000` покажут процесс; `pm2 list` покажет забытый экземпляр под другим именем.

**Статус.** Причина названа в обсуждении сопровождающими и совпадает с документацией; подтверждение автора не показано.

Сигналы и чистый перезапуск описаны в [документации pm2](https://pm2.keymetrics.io/docs/usage/signals-clean-restart/).
