Запуск исполняемого файла при выходе из docker -compose - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь выполнить файл javascript, используя nodejs при выходе из контейнера docker. Это то, что я получил до сих пор, и мои Dockerfile выглядят так, как показано ниже. Я не могу перехватить сигнал SIGINT во время выхода и, следовательно, не могу запустить функцию int_handler(). Есть ли проблема в сценарии, который я предоставил ниже?

Я запускаю команду docker-compose up, чтобы запустить сервер, а затем CTRL + C для выхода.

FROM node:10.16.0-slim

ENV NPM_CONFIG_PREFIX=/home/node/.npm-global

ENV PATH=$PATH:/home/node/.npm-global/bin

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

RUN mkdir -p /home/node/app/logs && chown -R node:node /home/node/app

WORKDIR /home/node/app

COPY package*.json ./

USER node

RUN npm install

COPY --chown=node:node . .

EXPOSE 8080

EXPOSE 8523

COPY ./docker-script.sh ./docker-script.sh

ENTRYPOINT ["./docker-script.sh"]

И содержимое файл docker. sh выглядит следующим образом:

#!/bin/bash
set -x

pid=0

int_handler() {
  echo "handler"
  node deactivator & pid="$!"
}

# setup handlers
trap 'kill ${!}; int_handler' SIGINT

# run application
node server & pid="$!"

# wait forever
while true
do
  tail -f /dev/null & wait ${!}
done

My docker -compose.yml file

version: '3'
services:
  mongo:
    image: mongo:3.6
  web:
    image: myimage/imagexyz:0.9.1
    restart: always
    ports:
     - "80:8081"
     - "443:8524"
    links:
     - mongo 
    depends_on: 
     - mongo

1 Ответ

1 голос
/ 14 февраля 2020

В этом есть пара мелких деталей, которые имеют значение.

Наиболее важным является то, что при отправке Ctrl + C на передний план docker-compose up, это эквивалентно docker-compose stop, что, в свою очередь, эквивалентно docker stop. Это посылает SIGTERM, а не SIGINT. Поможет изменить линию trap, чтобы поймать правильный сигнал.

При экспериментировании с этим после отправки Ctrl + C, docker-compose up остановит печать контейнера вывода. Он все еще генерируется, и вы все равно можете увидеть его с помощью docker-compose logs web.

Этот скрипт, кажется, выполняет много вещей в фоновом режиме, которые ему не нужны, и еще одну вещь меня бросает в глаза то, что ваша int_handler функция запускает фоновый процесс, как только контейнер собирается выйти. Это также имеет анти-паттерн запуска tail -f «для поддержания контейнера в живых», в то время как ваше приложение работает как побочный эффект.

Я получил разумное поведение от этой модификации вашего скрипт:

#!/bin/sh

int_handler() {
  echo "int_handler"
  # node deactivator

  # forcibly exit the script (and the container)
  exit 0
}

# trap SIGTERM here, not SIGINT
trap int_handler SIGTERM

echo start

# run the CMD from the Dockerfile or the `docker run` command
"$@" &

# wait for that process to exit
# (don't start an artificial `tail -f`)
# (you must `wait` or else the signal is delayed until
# the process exits on its own)
wait $!

и соответствующий тривиальный Dockerfile:

FROM alpine
COPY script /
ENTRYPOINT ["/script"]
CMD ["sleep", "15"]

Если функция trap не exit, то что-либо в скрипте точки входа после финального wait выполнит. Вы можете использовать это, если вы хотите безоговорочно очистить. Этот вариант всегда печатает stop, даже если вы docker stop контейнер, и завершается со статусом выхода из сценария.

#!/bin/sh
trap 'kill $pid' SIGTERM
echo start
"$@" &
pid=$!
wait $pid
rc=$?
echo stop
exit $rc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...