You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将信号转发给Docker中xfvb-run启动的进程?

解决Docker中xvfb-run下Node进程无法接收SIGTERM信号的问题

问题根源

xvfb-run本质是一个Shell脚本,当它作为tini的子进程启动Node时,不会主动将收到的SIGTERM信号转发给Node子进程。当Docker发送SIGTERM到容器的PID 1进程(tini)时,tini会把信号传给xvfb-run,但xvfb-run默认不会处理该信号,直接退出,导致Node进程被强制终止,无法执行优雅退出逻辑。

解决方案:自定义启动脚本转发信号

创建一个Shell启动脚本,手动管理Xvfb和Node进程,并负责将信号转发给Node,确保其能捕获SIGTERM并执行退出逻辑。

步骤1:编写启动脚本start.sh

#!/bin/sh
set -e

# 启动Xvfb服务,后台运行
Xvfb :0 -screen 0 1920x1080x8 &
XVFB_PID=$!

# 定义信号处理函数:转发SIGTERM给Node进程,等待其退出后再终止Xvfb
handle_shutdown() {
    echo "Forwarding SIGTERM to Node process..."
    if [ -n "$NODE_PID" ]; then
        kill -SIGTERM "$NODE_PID"
        wait "$NODE_PID"
    fi
    kill -SIGTERM "$XVFB_PID"
    wait "$XVFB_PID"
    exit 0
}

# 注册SIGTERM和SIGINT信号的处理逻辑
trap handle_shutdown SIGTERM SIGINT

# 启动Node进程,用exec确保Node成为当前Shell的子进程
exec node src &
NODE_PID=$!

# 等待Node进程结束,保持Shell进程运行
wait "$NODE_PID"

步骤2:修改Dockerfile

更新Dockerfile,复制启动脚本并设置为可执行,替换原CMD为执行该脚本:

# ... 原有安装TypeScript代码的步骤

COPY src ./src
COPY start.sh /start.sh
RUN npm i && pnpm build && chmod +x /start.sh

ENTRYPOINT ["/tini", "--"]
CMD ["/start.sh"]

步骤3:验证效果

  1. 重新构建镜像:docker build -t debug:signals .
  2. 启动容器:docker run --rm -t --name killme debug:signals
  3. 新终端发送SIGTERM:docker kill --signal=SIGTERM killme

此时会看到Node进程输出Received sigterm日志,实现优雅退出。

额外注意事项

  • 原Dockerfile中CMD的参数写法有误:'-s "-screen 0 1920x1080x8"'会被xvfb-run解析为一个完整参数,导致Xvfb启动参数错误。使用自定义脚本后直接指定Xvfb启动参数,避免了这个问题。
  • 确保tini版本正确(推荐v0.19.0+),能正确转发信号给子进程。

内容的提问来源于stack exchange,提问作者RunOrVeith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:45:56