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

如何在Docker中正确捕获SIGTERM信号?

Fixing SIGTERM Signal Forwarding to Gunicorn in Docker Containers

Why This Happens

When you run docker stop, Docker sends a SIGTERM signal to the PID 1 process inside the container. Your run_api.sh script is running as PID 1 here, but by default, Bash doesn't automatically forward signals to child processes (like your gunicorn server). That's why manually sending SIGTERM to gunicorn works, but docker stop doesn't—your shell is swallowing the signal instead of passing it along to the process that needs it.

Solutions

Option 1: Make Gunicorn PID 1 with exec

The simplest fix is to use exec when starting gunicorn. This replaces the shell process with gunicorn entirely, making gunicorn the new PID 1. Now, the SIGTERM from Docker goes directly to gunicorn, and your signal handling logic will trigger as expected.

Update your run_api.sh like this:

#!/bin/bash
cd /repo
PROCESSES=${1:-9}
LOCAL_DOCKER_PORT=${2:-7001}
# Use exec to replace the shell with gunicorn, making it PID 1
exec /opt/conda/envs/environment/bin/gunicorn --bind 0.0.0.0:$LOCAL_DOCKER_PORT --workers=$PROCESSES restful_api:app

Option 2: Add Signal Forwarding Logic to the Shell Script

If you need to keep the shell script as PID 1 (for example, to run pre-start setup tasks), you can add a trap to catch SIGTERM and explicitly forward it to the gunicorn process.

Here's the modified script:

#!/bin/bash
cd /repo
PROCESSES=${1:-9}
LOCAL_DOCKER_PORT=${2:-7001}

# Start gunicorn in the background and save its process ID
/opt/conda/envs/environment/bin/gunicorn --bind 0.0.0.0:$LOCAL_DOCKER_PORT --workers=$PROCESSES restful_api:app &
GUNICORN_PID=$!

# Define a handler to forward SIGTERM to gunicorn
handle_sigterm() {
    echo "Received SIGTERM, forwarding to gunicorn (PID: $GUNICORN_PID)"
    kill -TERM "$GUNICORN_PID"
    # Wait for gunicorn to exit cleanly before stopping the script
    wait "$GUNICORN_PID"
}

# Trap SIGTERM signals and run our handler
trap handle_sigterm SIGTERM

# Keep the shell running until gunicorn exits
wait "$GUNICORN_PID"

Extra Tips

  • Ensure run_api.sh has executable permissions: You can add RUN chmod +x /repo/run_api.sh to your Dockerfile, or set the permission locally before copying the script into the container.
  • If you're using Docker Compose, you can specify a custom stop signal with stop_signal: SIGTERM, but the above fixes should handle the core issue regardless of your orchestration tool.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 21:37:48