当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+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
函数没有退出
,那么在最终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/