黄中银 3 ماه پیش
والد
کامیت
6fd759724c
5فایلهای تغییر یافته به همراه241 افزوده شده و 80 حذف شده
  1. 6 12
      mixapi/Dockerfile
  2. 0 68
      mixapi/auto_update.sh
  3. 50 0
      mixapi/check_update.sh
  4. 83 0
      mixapi/common.sh
  5. 102 0
      mixapi/run.sh

+ 6 - 12
mixapi/Dockerfile

@@ -1,20 +1,14 @@
-# 使用curlimages/curl作为基础镜像(自带curl和sh)
-FROM curlimages/curl:latest
-
-# 切换到root用户进行设置
-USER root
+# 使用busybox:glibc作为基础镜像(自带wget、crond和sh)
+FROM busybox:glibc
 
 # 设置下载目录
 WORKDIR /app
 
-# 复制更新脚本
-COPY auto_update.sh /app/
-
-# 设置脚本可执行权限
-RUN chmod +x /app/auto_update.sh
+# 复制脚本
+COPY common.sh run.sh check_update.sh /app/
 
 # 构建时下载初始版本
-RUN sh /app/auto_update.sh OnlyUpdate
+RUN sh /app/run.sh OnlyUpdate
 
 # 暴露3000端口
 EXPOSE 3000
@@ -23,4 +17,4 @@ EXPOSE 3000
 WORKDIR /data
 
 # 启动命令 - 容器启动时检测更新并启动服务
-CMD ["sh", "/app/auto_update.bash"]
+CMD ["sh", "/app/run.sh"]

+ 0 - 68
mixapi/auto_update.sh

@@ -1,68 +0,0 @@
-#!/bin/sh
-
-# 自动更新为最新版本
-# 获取最新版本号
-ftag_name=$(curl -ksSL https://api.github.com/repos/aiprodcoder/MIXAPI/releases/latest | sed -n 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/p')
-
-# 如果获取失败,使用默认版本
-if [ -z "$ftag_name" ]; then
-    echo "无法获取最新版本号,使用默认版本 v1.2"
-    ftag_name="v1.2"
-fi
-
-echo "最新版本: ${ftag_name}"
-
-# 版本标记文件
-VERSION_FILE="/app/version.txt"
-
-# 检查是否需要更新
-if [ -f "$VERSION_FILE" ]; then
-    current_version=$(cat "$VERSION_FILE")
-    echo "当前版本: ${current_version}"
-    if [ "$current_version" = "$ftag_name" ]; then
-        echo "已是最新版本,无需更新"
-    else
-        echo "发现新版本,开始更新..."
-        rm -f /app/mixapi
-    fi
-else
-    echo "首次运行,开始下载..."
-fi
-
-# 如果可执行文件不存在,则下载
-if [ ! -f "/app/mixapi" ]; then
-    # 检测架构
-    arch="$(uname -m)"
-    echo "检测到架构: ${arch}"
-    
-    case "$arch" in
-        'x86_64')
-            download_url="https://github.com/aiprodcoder/MIXAPI/releases/download/${ftag_name}/mixapi-${ftag_name}-linux-amd64"
-            ;;
-        'aarch64')
-            download_url="https://github.com/aiprodcoder/MIXAPI/releases/download/${ftag_name}/mixapi-${ftag_name}-linux-arm64"
-            ;;
-        *)
-            echo "不支持的架构: ${arch}"
-            exit 1
-            ;;
-    esac
-    
-    echo "下载地址: ${download_url}"
-    curl -ksSL -o /app/mixapi "${download_url}"
-    
-    if [ $? -eq 0 ]; then
-        chmod +x /app/mixapi
-        echo "${ftag_name}" > "$VERSION_FILE"
-        echo "下载完成,版本: ${ftag_name}"
-    else
-        echo "下载失败"
-        exit 1
-    fi
-fi
-
-# 如果不是仅更新模式,则启动服务
-if [ "${1}" != "OnlyUpdate" ]; then
-    echo "启动 mixapi 服务..."
-    exec /app/mixapi
-fi

+ 50 - 0
mixapi/check_update.sh

@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# 加载公共函数库
+. /app/common.sh
+
+echo "[定时更新] $(date) 开始检测新版本..."
+
+# 获取最新版本号
+ftag_name=$(get_latest_version)
+
+if [ -z "$ftag_name" ]; then
+    echo "[定时更新] 无法获取最新版本号"
+    exit 0
+fi
+
+echo "[定时更新] 最新版本: ${ftag_name}"
+
+# 读取当前版本
+current_version=$(get_current_version)
+echo "[定时更新] 当前版本: ${current_version}"
+
+if [ "$current_version" = "$ftag_name" ]; then
+    echo "[定时更新] 已是最新版本,无需更新"
+    exit 0
+fi
+
+echo "[定时更新] 发现新版本,开始下载..."
+
+if download_version "$ftag_name" "$MIXAPI_NEW"; then
+    echo "[定时更新] 下载完成,准备热更新..."
+    
+    # 查找并停止旧进程
+    OLD_PID=$(find_mixapi_pid)
+    
+    if [ -n "$OLD_PID" ]; then
+        echo "[定时更新] 停止旧版本进程 (PID: $OLD_PID)..."
+        kill "$OLD_PID"
+        sleep 2
+    fi
+    
+    # 替换二进制文件
+    mv "$MIXAPI_NEW" "$MIXAPI_BIN"
+    save_version "$ftag_name"
+    
+    echo "[定时更新] 启动新版本..."
+    "$MIXAPI_BIN" &
+    echo "[定时更新] 新版本已启动 (PID: $!)"
+else
+    echo "[定时更新] 下载失败"
+fi

+ 83 - 0
mixapi/common.sh

@@ -0,0 +1,83 @@
+#!/bin/sh
+
+# 公共变量
+VERSION_FILE="/app/version.txt"
+MIXAPI_BIN="/app/mixapi"
+MIXAPI_NEW="/app/mixapi.new"
+UPDATE_SCRIPT="/app/check_update.sh"
+CRON_FILE="/var/spool/cron/crontabs/root"
+DEFAULT_VERSION="v1.2"
+GITHUB_API_URL="https://api.github.com/repos/aiprodcoder/MIXAPI/releases/latest"
+GITHUB_DOWNLOAD_BASE="https://github.com/aiprodcoder/MIXAPI/releases/download"
+
+# 获取最新版本号
+get_latest_version() {
+    wget -qO- "$GITHUB_API_URL" | sed -n 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/p'
+}
+
+# 获取下载URL
+get_download_url() {
+    local version=$1
+    local arch="$(uname -m)"
+    
+    case "$arch" in
+        'x86_64')
+            echo "${GITHUB_DOWNLOAD_BASE}/${version}/mixapi-${version}-linux-amd64"
+            ;;
+        'aarch64')
+            echo "${GITHUB_DOWNLOAD_BASE}/${version}/mixapi-${version}-linux-arm64"
+            ;;
+        *)
+            echo ""
+            ;;
+    esac
+}
+
+# 下载指定版本
+# 参数: $1=版本号, $2=目标文件路径
+download_version() {
+    local version=$1
+    local target=$2
+    local url=$(get_download_url "$version")
+    
+    if [ -z "$url" ]; then
+        echo "不支持的架构: $(uname -m)"
+        return 1
+    fi
+    
+    echo "下载地址: ${url}"
+    wget -qO "$target" "$url"
+    
+    if [ $? -eq 0 ] && [ -s "$target" ]; then
+        chmod +x "$target"
+        return 0
+    else
+        rm -f "$target"
+        return 1
+    fi
+}
+
+# 获取当前版本
+get_current_version() {
+    if [ -f "$VERSION_FILE" ]; then
+        cat "$VERSION_FILE"
+    else
+        echo ""
+    fi
+}
+
+# 保存版本号
+save_version() {
+    echo "$1" > "$VERSION_FILE"
+}
+
+# 查找 mixapi 进程 PID
+find_mixapi_pid() {
+    local pid=""
+    pid=$(ps aux 2>/dev/null | grep "$MIXAPI_BIN" | grep -v grep | awk '{print $1}' | head -1)
+    if [ -z "$pid" ]; then
+        # busybox ps 格式不同,尝试另一种方式
+        pid=$(ps | grep "$MIXAPI_BIN" | grep -v grep | awk '{print $1}' | head -1)
+    fi
+    echo "$pid"
+}

+ 102 - 0
mixapi/run.sh

@@ -0,0 +1,102 @@
+#!/bin/sh
+
+# 加载公共函数库
+. /app/common.sh
+
+# 设置定时任务
+setup_cron() {
+    # 获取当前时间的上一分钟作为执行时间
+    # 格式: 分 时 * * *
+    current_min=$(date +%M)
+    current_hour=$(date +%H)
+    
+    # 计算上一分钟对应的分钟和小时
+    if [ "$current_min" -eq 0 ]; then
+        cron_min=59
+        if [ "$current_hour" -eq 0 ]; then
+            cron_hour=23
+        else
+            cron_hour=$((current_hour - 1))
+        fi
+    else
+        cron_min=$((current_min - 1))
+        cron_hour=$current_hour
+    fi
+    
+    # 去掉前导零(避免被解释为八进制)
+    cron_min=$(echo $cron_min | sed 's/^0//')
+    cron_hour=$(echo $cron_hour | sed 's/^0//')
+    
+    # 如果为空则设为0
+    [ -z "$cron_min" ] && cron_min=0
+    [ -z "$cron_hour" ] && cron_hour=0
+    
+    cron_entry="$cron_min $cron_hour * * * sh $UPDATE_SCRIPT >> /app/update.log 2>&1"
+    
+    echo "设置定时任务: 每天 ${cron_hour}:${cron_min} 执行更新检测"
+    
+    # 确保cron目录存在
+    mkdir -p /var/spool/cron/crontabs
+    
+    # 删除旧的更新任务(如果存在)
+    if [ -f "$CRON_FILE" ]; then
+        grep -v "$UPDATE_SCRIPT" "$CRON_FILE" > "${CRON_FILE}.tmp" 2>/dev/null || true
+        mv "${CRON_FILE}.tmp" "$CRON_FILE"
+    fi
+    
+    # 添加新的定时任务
+    echo "$cron_entry" >> "$CRON_FILE"
+    
+    # 启动crond(busybox crond)
+    crond -b -l 8
+    echo "crond 已启动"
+}
+
+# 仅更新模式(构建时使用)
+if [ "${1}" = "OnlyUpdate" ]; then
+    echo "构建模式:下载初始版本..."
+    
+    ftag_name=$(get_latest_version)
+    
+    if [ -z "$ftag_name" ]; then
+        echo "无法获取最新版本号,使用默认版本 ${DEFAULT_VERSION}"
+        ftag_name="$DEFAULT_VERSION"
+    fi
+    
+    echo "版本: ${ftag_name}"
+    
+    if download_version "$ftag_name" "$MIXAPI_BIN"; then
+        save_version "$ftag_name"
+        echo "下载完成"
+    else
+        echo "下载失败"
+        exit 1
+    fi
+    
+    exit 0
+fi
+
+# 正常启动模式
+echo "启动 mixapi 服务..."
+
+# 检查本地是否有可执行文件
+if [ ! -f "$MIXAPI_BIN" ]; then
+    echo "本地没有可执行文件,先下载..."
+    ftag_name=$(get_latest_version)
+    if [ -z "$ftag_name" ]; then
+        ftag_name="$DEFAULT_VERSION"
+    fi
+    download_version "$ftag_name" "$MIXAPI_BIN"
+    save_version "$ftag_name"
+fi
+
+# 设置定时任务
+setup_cron
+
+# 启动时先执行一次更新检测(后台)
+echo "启动时执行一次更新检测..."
+sh "$UPDATE_SCRIPT" &
+
+# 启动 mixapi(前台运行,保持容器运行)
+echo "启动 mixapi..."
+exec "$MIXAPI_BIN"