javascript - 当 docker-compose 退出时运行可执行文件

标签 javascript node.js shell docker docker-compose

当docker容器退出时,我尝试使用nodejs执行javascript文件。这是我到目前为止所得到的,我的 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-script.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

我的 docker-compose.yml 文件

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

最佳答案

其中有几个小细节很重要。

最重要的是,当您将 Ctrl+C 发送到前台 docker-compose up 时,它相当于 docker-compose stop,这相当于 docker stop 。它发送的是 SIGTERM,而不是 SIGINT。更改您的trap线以捕获正确的信号会有所帮助。

在对此进行实验时,一旦您发送了 Ctrl+Cdocker-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函数没有退出,那么在最终wait之后入口点脚本中的任何内容都将执行。如果你想无条件清理,你可以使用这个。即使您 docker stop 容器,此变体也始终打印 stop,并以脚本的退出状态退出。

#!/bin/sh
trap 'kill $pid' SIGTERM
echo start
"$@" &
pid=$!
wait $pid
rc=$?
echo stop
exit $rc

关于javascript - 当 docker-compose 退出时运行可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60223616/

相关文章:

javascript - 你如何使用 browserify 从 node_modules 加载 typescript 模块?

shell - 找到所有的 zip,并解压到位 - Unix

javascript - Chrome 调试器中不显示扩展 .js 文件

javascript - 正则表达式最后一个空格问题

javascript - NWJS 中的跨域源安全

node.js - 在 nodeJS 中运行 Mocha 测试时出错

linux - 有没有办法可以使用 "if"分支来检查 U 盘是否已连接?

linux - 如何使用 Linux 命令或 Shell 脚本读取文件的特定行

javascript - 在 emscripten 中更改默认命名空间 'Module'

javascript - 在调整窗口大小之前,部分 div 隐藏着微小的滚动条