File size: 5,084 Bytes
5bfb40b d85e519 5bfb40b d85e519 5bfb40b d85e519 8783c2d 5bfb40b 8783c2d d85e519 8783c2d 5bfb40b d85e519 5bfb40b d85e519 5bfb40b 8783c2d 5bfb40b d85e519 8783c2d d85e519 5bfb40b d85e519 8783c2d 5bfb40b d85e519 5bfb40b d85e519 5bfb40b 69b897d 5bfb40b 8783c2d 5bfb40b 8783c2d 5bfb40b 8783c2d 5bfb40b 8783c2d 5bfb40b 0b18167 8783c2d 5bfb40b 753e568 8783c2d 5bfb40b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
#!/bin/sh
# shellcheck shell=sh
set -e
TS() { date "+%Y-%m-%d %H:%M:%S"; }
log() { echo "[$(TS)] [entrypoint] $*"; }
# -----------------------------------------------------------------------------
# 基础目录
# -----------------------------------------------------------------------------
mkdir -p /app/logs /app/data /app/temp
# Redis 数据目录放在 /app/data/redis,这样能随备份一起保存/恢复
REDIS_DIR="${REDIS_DIR:-/app/data/redis}"
mkdir -p "${REDIS_DIR}"
# -----------------------------------------------------------------------------
# 导出备份相关环境变量(给子进程可见)
# -----------------------------------------------------------------------------
export HF_TOKEN="${HF_TOKEN:-}"
export DATASET_ID="${DATASET_ID:-}"
export SYNC_INTERVAL MAX_BACKUPS BACKUP_PREFIX BACKUP_PATHS BACKUP_EXCLUDE
# 若未指定,给出对持久化友好的默认值(相对路径,配合 tar -C /)
BACKUP_PATHS="${BACKUP_PATHS:-app/data,app/data/redis}"
BACKUP_EXCLUDE="${BACKUP_EXCLUDE:-*.tmp,*.cache,**/.DS_Store}"
export BACKUP_PATHS BACKUP_EXCLUDE
# -----------------------------------------------------------------------------
# 在任何服务启动前先尝试恢复数据(包含 Redis 的 RDB/AOF)
# -----------------------------------------------------------------------------
if [ -n "$HF_TOKEN" ] && [ -n "$DATASET_ID" ]; then
/app/tools/hf-backup.sh restore || log "Restore skipped/failed, continue."
else
log "未配置 HF_TOKEN/DATASET_ID,跳过恢复。"
fi
# -----------------------------------------------------------------------------
# 启动(内置或外置)Redis
# -----------------------------------------------------------------------------
REDIS_HOST="${REDIS_HOST:-127.0.0.1}"
REDIS_PORT="${REDIS_PORT:-6379}"
start_internal_redis="false"
case "$REDIS_HOST" in
""|"127.0.0.1"|"localhost") start_internal_redis="true" ;;
esac
if [ "$start_internal_redis" = "true" ]; then
log "Starting embedded Redis on 127.0.0.1:${REDIS_PORT} ..."
if [ -n "${REDIS_PASSWORD:-}" ]; then
redis-server \
--port "${REDIS_PORT}" --bind 127.0.0.1 \
--dir "${REDIS_DIR}" \
--dbfilename dump.rdb \
--appendonly yes --appendfilename appendonly.aof \
--appendfsync everysec \
--save 60 1 \
--requirepass "${REDIS_PASSWORD}" &
else
redis-server \
--port "${REDIS_PORT}" --bind 127.0.0.1 \
--dir "${REDIS_DIR}" \
--dbfilename dump.rdb \
--appendonly yes --appendfilename appendonly.aof \
--appendfsync everysec \
--save 60 1 &
fi
else
log "Using EXTERNAL Redis at ${REDIS_HOST}:${REDIS_PORT}, skip embedded Redis."
fi
# 等待 Redis 就绪
log "Waiting for Redis on ${REDIS_HOST}:${REDIS_PORT} ..."
i=0
while :; do
if [ -n "${REDIS_PASSWORD:-}" ]; then
if redis-cli -h "${REDIS_HOST}" -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}" ping >/dev/null 2>&1; then
break
fi
else
if redis-cli -h "${REDIS_HOST}" -p "${REDIS_PORT}" ping >/dev/null 2>&1; then
break
fi
fi
i=$((i+1))
if [ "$i" -ge 60 ]; then
log "Redis not ready after 60s, exit."
exit 1
fi
sleep 1
done
log "Redis is ready."
# -----------------------------------------------------------------------------
# 备份守护进程(可选:开机先做一份一次性备份)
# BACKUP_ON_START=true 时,先执行一次上传,随后开启守护
# -----------------------------------------------------------------------------
if [ -n "$HF_TOKEN" ] && [ -n "$DATASET_ID" ]; then
if [ "${BACKUP_ON_START:-false}" = "true" ]; then
/app/tools/hf-backup.sh once || log "First backup failed (ignored)."
fi
# 同时输出到控制台和日志文件,便于在 HF 控制台直接看到
/app/tools/hf-backup.sh daemon 2>&1 | tee -a /app/logs/hf-backup.log &
log "启动 HF Dataset 备份服务(间隔 ${SYNC_INTERVAL:-3600}s,保留 ${MAX_BACKUPS:-10} 份)"
else
log "未配置 HF_TOKEN/DATASET_ID,跳过备份守护进程。"
fi
# -----------------------------------------------------------------------------
# 可选:强制重置管理员(会删除 init.json)
# -----------------------------------------------------------------------------
if [ "${FORCE_ADMIN_RESET:-false}" = "true" ]; then
log "FORCE_ADMIN_RESET=true, remove /app/data/init.json"
rm -f /app/data/init.json
fi
# -----------------------------------------------------------------------------
# 初始化管理员 / 应用准备
# -----------------------------------------------------------------------------
if [ -n "${ADMIN_USERNAME:-}" ] && [ -n "${ADMIN_PASSWORD:-}" ]; then
log "Bootstrapping admin user: ${ADMIN_USERNAME}"
else
log "ADMIN_USERNAME/ADMIN_PASSWORD 未设置,将按已有 init.json 或默认逻辑处理。"
fi
npm run setup
# -----------------------------------------------------------------------------
# 启动应用
# -----------------------------------------------------------------------------
HOST="${HOST:-0.0.0.0}"
PORT="${PORT:-7860}"
log "Starting app on ${HOST}:${PORT} ..."
exec node src/app.js
|