Как корректно завершить работу приложения экспресс-докера?

Недавно я смотрел курс по Docker, где преподаватель объяснял, что для корректного закрытия контейнера код ошибки должен быть 0, проблема в том, что мой контейнер завершает свой процесс с кодом 137.

Поэтому я искал и пытался каким-то образом сделать код выхода 0, но мне это не удалось.

индекс.js:

const express = require("express");

const app = express();

const port = 3000;

app.get("/", (req, res) => {
  res.send("Hello, Express!");
});

app.listen(port, () => {
  console.info(`Server is running on port ${port}`);
});

Докерфайл:

FROM node:latest

COPY ["package.json", "package-lock.json", "/usr/src/"]

WORKDIR /usr/src/

RUN npm install

COPY [".", "/usr/src/"]

EXPOSE 3000

CMD ["node", "index.js"]

Чтобы использовать этот контейнер, я сделал:

docker build -t express .

Затем

docker run --name app -p 5000:3000 -d express

Чтобы проверить процесс приложения, я сделал:

docker exec app ps -ef

Выход:

UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  1 11:40 ?        00:00:00 node index.js
root          14       0 50 11:40 ?        00:00:00 ps -ef

Это результат после «приложения остановки докера», контейнер ждет около 10 секунд перед остановкой.

Это вывод после docker ps -l:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                        PORTS     NAMES
7e7916725120   express   "docker-entrypoint.s…"   24 seconds ago   Exited (137) 10 seconds ago             app

Я загрузил репо на случай, если оно вам понадобится:

https://github.com/ivandez/express-so

Вы можете обрабатывать такие события, как SIGINT и SIGTERM, используя process.on(..., и корректно завершать работу. Но, к сожалению, docker stop отправляет событие SIGKILL, которое, я думаю, невозможно обработать. Код выхода 137 означает, что процесс был завершен с помощью SIGKILL. Вы можете указать сигнал для отправки docker stop с помощью -s <signal>. Если вы готовы это сделать, вы можете использовать SIGTERM. Затем вы можете обработать это в Node и выйти с кодом 0.

Hans Kilian 07.03.2024 13:28

docker stop всегда отправляет первый SIGTERM для остановки контейнера, а через определенное время Docker отправит SIGKILL. Обновлено: источник: docs.docker.com/reference/cli/docker/container/stop

Ivandez 07.03.2024 20:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
107
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

когда ты это делаешь: docker stop $(docker ps -q -l) или что-то вроде docker stop abcedef после docker ps -a docker stop сначала отправит SIGTERM. Вам нужно обработать это на стороне Node.js:

process.on("SIGTERM", function(code_signal_error){
    process.exit(0) //or whatever you want
})

Для меня код выхода Node редко имеет значение, поэтому я обычно делаю что-то вроде:

[`exit`, `SIGQUIT`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach(function(evt){
        process.on(evt, this);
    }, once(
        function(code_signal_error){
            //decide what to do here. Terminate workers etc.
            //do not forget to call process.exit(0) or whatever value makes sense to you.
        }
    ));

once выше приведена реализация, которая возвращает функцию, которая выполняется только один раз, вы можете найти множество реализаций, я использую собственную. Причина в том, что Docker Stop отправит SIGKILL через некоторое время, если SIGTERM не вступит в силу.

Другие вопросы по теме