Files
zhuiguang-ai/scripts/entrypoint-cron.sh
T

162 lines
5.4 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# =============================================================================
# 追光AI CRON 容器启动入口
# - 用 supercronic 调度 /app/crontab.txt 里的任务
# - 跟 host cron 行为一致,但完全在容器内
# - 增强:信号处理、错误处理、日志轮转集成
# =============================================================================
set -e
cd /app
# =============================================================================
# 信号处理 - 优雅关闭
# =============================================================================
SUPERCRONIC_PID=""
cleanup() {
echo "[entrypoint-cron] Received shutdown signal, stopping gracefully..."
if [ -n "$SUPERCRONIC_PID" ]; then
kill -TERM "$SUPERCRONIC_PID" 2>/dev/null || true
# 等待进程结束,最多 30 秒
for i in $(seq 1 30); do
if ! kill -0 "$SUPERCRONIC_PID" 2>/dev/null; then
echo "[entrypoint-cron] Process exited cleanly"
break
fi
sleep 1
done
# 如果还没退出,强制终止
if kill -0 "$SUPERCRONIC_PID" 2>/dev/null; then
echo "[entrypoint-cron] Force killing process..."
kill -9 "$SUPERCRONIC_PID" 2>/dev/null || true
fi
fi
exit 0
}
trap cleanup TERM INT QUIT
# =============================================================================
# 日志轮转配置(通过环境变量控制)
# =============================================================================
# LOG_MAX_SIZE: 单个日志文件最大大小(默认 100M)
# LOG_MAX_FILES: 保留的历史日志文件数(默认 7)
# LOG_COMPRESS: 是否压缩历史日志(默认 true)
LOG_MAX_SIZE="${LOG_MAX_SIZE:-100M}"
LOG_MAX_FILES="${LOG_MAX_FILES:-7}"
LOG_COMPRESS="${LOG_COMPRESS:-true}"
# 如果启用了日志文件输出,配置 logrotate
if [ -n "$LOG_FILE" ]; then
echo "[entrypoint-cron] Log file configured: $LOG_FILE"
echo "[entrypoint-cron] Log rotation: max_size=$LOG_MAX_SIZE, max_files=$LOG_MAX_FILES, compress=$LOG_COMPRESS"
# 创建 logrotate 配置
cat > /etc/logrotate.d/zhuiguang-cron <<EOF
$LOG_FILE {
size $LOG_MAX_SIZE
rotate $LOG_MAX_FILES
compress
delaycompress
missingok
notifempty
create 0644 root root
postrotate
# 通知 supercronic 重新打开日志文件(如果支持)
true
endscript
}
EOF
fi
# =============================================================================
# Seed data volume if empty
# =============================================================================
if [ ! -f /app/data/bot-characters.json ] && [ -d /app/data-seed ]; then
echo "[entrypoint] Seeding data volume..."
cp -r /app/data-seed/* /app/data/
fi
# =============================================================================
# .env 校验
# =============================================================================
if [ ! -f /app/.env ]; then
echo "[entrypoint-cron] FATAL: /app/.env not found. Mount .env file into container."
exit 1
fi
# =============================================================================
# crontab 文件校验
# =============================================================================
if [ ! -f /app/crontab.txt ]; then
echo "[entrypoint-cron] FATAL: /app/crontab.txt not found. Mount crontab into container."
exit 1
fi
# =============================================================================
# 健康检查端点(可选)
# =============================================================================
if [ "$HEALTH_CHECK_ENABLED" = "true" ]; then
HEALTH_PORT="${HEALTH_CHECK_PORT:-8311}"
echo "[entrypoint-cron] Health check enabled on port $HEALTH_PORT"
# 启动简单的健康检查 HTTP 服务器
(
while true; do
echo -e "HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK" | nc -l -p "$HEALTH_PORT" -q 1 2>/dev/null || true
done
) &
HEALTH_PID=$!
echo "[entrypoint-cron] Health check server started (PID: $HEALTH_PID)"
fi
# =============================================================================
# supercronic 启动
# =============================================================================
echo "[entrypoint-cron] Starting supercronic..."
echo "[entrypoint-cron] crontab:"
sed 's/^/ /' /app/crontab.txt
# 构建启动参数
SUPERCRONIC_ARGS=""
# Prometheus 监控(可选)
if [ "$PROMETHEUS_ENABLED" != "false" ]; then
PROMETHEUS_PORT="${PROMETHEUS_PORT:-8310}"
SUPERCRONIC_ARGS="$SUPERCRONIC_ARGS -prometheus-listen-address 0.0.0.0:$PROMETHEUS_PORT"
echo "[entrypoint-cron] Prometheus metrics enabled on port $PROMETHEUS_PORT"
fi
# 日志分离(可选)
if [ "$SPLIT_LOGS" = "true" ]; then
SUPERCRONIC_ARGS="$SUPERCRONIC_ARGS -split-logs"
echo "[entrypoint-cron] Split logs enabled (stdout/stderr separated)"
fi
# 调试模式
if [ "$DEBUG" = "true" ]; then
SUPERCRONIC_ARGS="$SUPERCRONIC_ARGS -debug"
echo "[entrypoint-cron] Debug mode enabled"
fi
# 启动 supercronic(后台运行以捕获 PID)
/usr/local/bin/supercronic-linux-amd64 $SUPERCRONIC_ARGS /app/crontab.txt &
SUPERCRONIC_PID=$!
echo "[entrypoint-cron] Supercronic started with PID: $SUPERCRONIC_PID"
echo "[entrypoint-cron] Container ready"
# 等待 supercronic 进程(同时保持信号处理能力)
wait "$SUPERCRONIC_PID"
EXIT_CODE=$?
echo "[entrypoint-cron] Supercronic exited with code: $EXIT_CODE"
# 清理健康检查服务器
if [ -n "$HEALTH_PID" ]; then
kill "$HEALTH_PID" 2>/dev/null || true
fi
exit $EXIT_CODE