【保留统计数据】CliProxyApi自动更新脚本分享

2026-04-29 08:242阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

不知道为什么,总喜欢看自己的使用统计数据。

最近上手部署了docker的CliProxyApi,管理我御三家的AI账号,用了段时间,昨晚更新的时候发现使用的统计数据给重置了…有种玩游戏闯关重头再来的感觉

查了文档,扒了扒源码看了看,目前似乎统计数据没有持久化,是丢内存里的。所以有了这个脚本,暂时对付对付。

逻辑很简单,就是先导出、更新重启,再导入。测了下没啥问题,分享给有需要的佬友们。

image1954×1146 184 KB


主要修改三个地方:

  1. 一个自己放docker-compose.yml的路径,可以pwd查看

BASE_DIR="/root/cliproxyapi"

  1. 一个是认证密码:

MANAGEMENT_PASSWORD="your-pass-word"

  1. 一个是容器的名字,输入docker ps可以查看复制过来:

CONTAINER_NAME="cli-proxy-api"

然后可以设置下定时执行,就定时会更新镜像,如果已经是最新镜像,就会跳过

# 编辑添加定时任务 crontab -e # 定时更新 每30min检查一次 */30 * * * * /root/cliproxyapi/upgrade.sh upgrade

image1420×464 65.7 KB


  • 完整脚本:

#!/usr/bin/env bash set -euo pipefail # ============================================================ # CLIProxyAPI 升级/备份工具脚本 # # 本脚本提供 3 个子命令,通过第一个参数选择要执行的功能: # # 1) export 仅导出当前使用统计为 JSON 文件(做备份用) # 2) import 从最近一次的 JSON 备份中导入使用统计 # 3) upgrade 一键升级流程:先导出 -> 升级容器 -> 再导入 # # 使用示例: # ./upgrade.sh export # 只备份当前使用统计 # ./upgrade.sh import # 只从最近的备份恢复使用统计 # ./upgrade.sh upgrade # 完整执行升级流程(推荐) # ============================================================ # ===== 基本配置 ===== # CLIProxyAPI 在宿主机上的工作目录(通常是放 docker-compose.yml 的目录) BASE_DIR="/root/cliproxyapi" # 统计信息备份目录 STATS_DIR="${BASE_DIR}/stats" # 管理面板访问密码(对应 CLIProxyAPI 管理端的 X-Management-Key) MANAGEMENT_PASSWORD="your-pass-word" # CLIProxyAPI 服务访问地址(我这里修改端口) HOST="127.0.0.1" PORT="8317" # docker-compose 中定义的服务名称(注意:是 service 名,不是镜像名) CONTAINER_NAME="cli-proxy-api" # 管理 API 基础地址 API_BASE="http://${HOST}:${PORT}/v0/management" AUTH_HEADER="X-Management-Key: ${MANAGEMENT_PASSWORD}" # 确保备份目录存在 mkdir -p "${STATS_DIR}" # 生成时间戳,格式:20250128-153045 timestamp() { date +"%Y%m%d-%H%M%S" } # ------------------------------------------------------------ # 子命令:export # 功能:从 CLIProxyAPI 导出当前使用统计,并保存为 JSON 备份文件 # 用法:./upgrade.sh export # ------------------------------------------------------------ export_usage() { local ts file ts="$(timestamp)" file="${STATS_DIR}/usage-${ts}.json" echo "导出使用统计到 ${file}..." # 使用 curl 同时获取响应体和 HTTP 状态码 RESPONSE=$(curl -sS -w "\n%{http_code}" -H "${AUTH_HEADER}" "${API_BASE}/usage/export") HTTP_CODE=$(echo "${RESPONSE}" | tail -n1) BODY=$(echo "${RESPONSE}" | sed '$d') if [[ "${HTTP_CODE}" != "200" ]]; then echo "导出失败 (HTTP ${HTTP_CODE}): ${BODY}" return 1 fi echo "${BODY}" > "${file}" echo "导出完成: ${file}" } # ------------------------------------------------------------ # 子命令:import # 功能:从 stats 目录中“最新的” usage-*.json 备份文件中导入使用统计 # 用法:./upgrade.sh import # 场景:升级后、迁移后,需要把使用统计恢复回来 # ------------------------------------------------------------ import_latest_usage() { local latest latest="$(ls -1t "${STATS_DIR}"/usage-*.json 2>/dev/null | head -n 1 || true)" if [[ -z "${latest}" ]]; then echo "没有找到可用的使用统计备份,跳过导入。" return 0 fi echo "导入最近一次的使用统计:${latest} ..." RESPONSE=$(curl -sS -w "\n%{http_code}" -X POST \ -H "${AUTH_HEADER}" \ -H "Content-Type: application/json" \ -d @"${latest}" \ "${API_BASE}/usage/import") HTTP_CODE=$(echo "${RESPONSE}" | tail -n1) BODY=$(echo "${RESPONSE}" | sed '$d') if [[ "${HTTP_CODE}" == "200" ]]; then echo "导入完成。" else echo "导入失败 (HTTP ${HTTP_CODE}): ${BODY}" return 1 fi } # ------------------------------------------------------------ # 辅助函数:等待 CLIProxyAPI 服务启动并能正常响应 HTTP 200 # 在 upgrade 流程中用于“拉起容器后等待后端真正就绪” # ------------------------------------------------------------ wait_for_server() { echo "等待 CLIProxyAPI 启动..." for _ in $(seq 1 60); do if curl -sS -o /dev/null -w "%{http_code}" "http://${HOST}:${PORT}/" 2>/dev/null | grep -q "200"; then echo "服务已就绪。" return 0 fi sleep 2 done echo "等待服务超时,请检查容器是否正常启动。" >&2 return 1 } # ------------------------------------------------------------ # 子命令:upgrade (一键升级) # # 完整流程: # 1. 导出当前使用统计(避免升级丢数据) # 2. 使用 docker compose 拉取最新镜像并重启 cli-proxy-api 容器 # 3. 等待 CLIProxyAPI HTTP 服务就绪 # 4. 从刚刚导出的备份中重新导入使用统计 # # 用法:./upgrade.sh upgrade # ------------------------------------------------------------ upgrade() { echo "=== 步骤 1:导出当前使用统计 ===" export_usage echo "=== 步骤 2:检查并拉取最新镜像 ===" cd "${BASE_DIR}" # 获取当前容器使用的镜像名称(从 docker-compose.yml 解析或从运行中的容器获取) # 优先从运行中的容器获取,如果没有运行则从 docker-compose config 解析 if docker ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then # 容器正在运行,从容器获取镜像名 current_image=$(docker inspect --format='{{.Config.Image}}' "${CONTAINER_NAME}" 2>/dev/null || true) else # 容器未运行,从 docker-compose config 解析镜像名 current_image=$(docker compose config --format json 2>/dev/null | grep -o '"image":"[^"]*"' | head -1 | cut -d'"' -f4 || true) fi if [[ -z "${current_image}" ]]; then echo "警告:无法确定当前镜像名称,将强制拉取并重启。" >&2 current_image="unknown" else echo "当前使用的镜像:${current_image}" # 获取 pull 前的镜像 ID(如果镜像存在) image_id_before=$(docker image inspect "${current_image}" --format='{{.Id}}' 2>/dev/null || echo "") fi # 执行 pull echo "正在拉取最新镜像..." if ! docker compose pull "${CONTAINER_NAME}"; then echo "拉取镜像失败,请检查 docker compose 配置和网络。" >&2 return 1 fi # 获取 pull 后的镜像 ID if [[ "${current_image}" != "unknown" ]]; then image_id_after=$(docker image inspect "${current_image}" --format='{{.Id}}' 2>/dev/null || echo "") # 如果 pull 前后镜像 ID 相同,说明没有新镜像 if [[ -n "${image_id_before}" && -n "${image_id_after}" && "${image_id_before}" == "${image_id_after}" ]]; then echo "检测到镜像已是最新版本(镜像 ID 未变化),本次无需升级容器,后续步骤(重启 / 导入)将跳过。" echo "=== 升级流程结束(无新镜像,无需变更) ===" return 0 fi fi echo "检测到有新镜像或镜像已更新,继续执行容器重启和数据导入。" echo "=== 步骤 3:重启容器 ===" docker compose stop "${CONTAINER_NAME}" || true docker compose up -d "${CONTAINER_NAME}" echo "=== 步骤 4:等待服务就绪 ===" wait_for_server echo "=== 步骤 5:导入使用统计 ===" import_latest_usage echo "=== 升级流程完成 ===" } # ========= 命令行入口 ========= # 如果你想“无参数就默认执行 upgrade”,可以把下面的 "${1:-}" 改成: # cmd="${1:-upgrade}" # 然后把 case 的变量改成 "${cmd}" 即可。 # # 当前版本设计为“必须显式传入子命令”,这样更安全,不容易误操作。 case "${1:-}" in export) export_usage ;; import) import_latest_usage ;; upgrade) upgrade ;; *) echo "用法: $0 {export|import|upgrade}" >&2 echo echo "说明:" echo " export 只导出当前使用统计到 stats 目录" echo " import 只从最近的 usage-*.json 备份文件中导入使用统计" echo " upgrade 先导出,再升级容器,最后导入(推荐用于升级系统)" exit 1 ;; esac 网友解答:


--【壹】--:

不客气


--【贰】--:

这个功能好


--【叁】--:

好样的,回头试试看


--【肆】--:

正好用上,我也一直每天凌晨用脚本自动更新,但数据全丢了,现在好了


--【伍】--:

哇,感谢大佬


--【陆】--:

可以很实用


--【柒】--:

谢谢大佬,刚刚重启了,数据全没了,好多了


--【捌】--:

感谢大佬


--【玖】--:

感谢大佬


--【拾】--:

谢谢大佬,正好要用到,认证文件能保留吗


--【拾壹】--:

感谢大佬


--【拾贰】--:

mark一记,谢谢佬


--【拾叁】--:

同,回头试试


--【拾肆】--:

是的,心痛ing 虽然可能是小众需求 暂时顶顶用着

问题描述:

不知道为什么,总喜欢看自己的使用统计数据。

最近上手部署了docker的CliProxyApi,管理我御三家的AI账号,用了段时间,昨晚更新的时候发现使用的统计数据给重置了…有种玩游戏闯关重头再来的感觉

查了文档,扒了扒源码看了看,目前似乎统计数据没有持久化,是丢内存里的。所以有了这个脚本,暂时对付对付。

逻辑很简单,就是先导出、更新重启,再导入。测了下没啥问题,分享给有需要的佬友们。

image1954×1146 184 KB


主要修改三个地方:

  1. 一个自己放docker-compose.yml的路径,可以pwd查看

BASE_DIR="/root/cliproxyapi"

  1. 一个是认证密码:

MANAGEMENT_PASSWORD="your-pass-word"

  1. 一个是容器的名字,输入docker ps可以查看复制过来:

CONTAINER_NAME="cli-proxy-api"

然后可以设置下定时执行,就定时会更新镜像,如果已经是最新镜像,就会跳过

# 编辑添加定时任务 crontab -e # 定时更新 每30min检查一次 */30 * * * * /root/cliproxyapi/upgrade.sh upgrade

image1420×464 65.7 KB


  • 完整脚本:

#!/usr/bin/env bash set -euo pipefail # ============================================================ # CLIProxyAPI 升级/备份工具脚本 # # 本脚本提供 3 个子命令,通过第一个参数选择要执行的功能: # # 1) export 仅导出当前使用统计为 JSON 文件(做备份用) # 2) import 从最近一次的 JSON 备份中导入使用统计 # 3) upgrade 一键升级流程:先导出 -> 升级容器 -> 再导入 # # 使用示例: # ./upgrade.sh export # 只备份当前使用统计 # ./upgrade.sh import # 只从最近的备份恢复使用统计 # ./upgrade.sh upgrade # 完整执行升级流程(推荐) # ============================================================ # ===== 基本配置 ===== # CLIProxyAPI 在宿主机上的工作目录(通常是放 docker-compose.yml 的目录) BASE_DIR="/root/cliproxyapi" # 统计信息备份目录 STATS_DIR="${BASE_DIR}/stats" # 管理面板访问密码(对应 CLIProxyAPI 管理端的 X-Management-Key) MANAGEMENT_PASSWORD="your-pass-word" # CLIProxyAPI 服务访问地址(我这里修改端口) HOST="127.0.0.1" PORT="8317" # docker-compose 中定义的服务名称(注意:是 service 名,不是镜像名) CONTAINER_NAME="cli-proxy-api" # 管理 API 基础地址 API_BASE="http://${HOST}:${PORT}/v0/management" AUTH_HEADER="X-Management-Key: ${MANAGEMENT_PASSWORD}" # 确保备份目录存在 mkdir -p "${STATS_DIR}" # 生成时间戳,格式:20250128-153045 timestamp() { date +"%Y%m%d-%H%M%S" } # ------------------------------------------------------------ # 子命令:export # 功能:从 CLIProxyAPI 导出当前使用统计,并保存为 JSON 备份文件 # 用法:./upgrade.sh export # ------------------------------------------------------------ export_usage() { local ts file ts="$(timestamp)" file="${STATS_DIR}/usage-${ts}.json" echo "导出使用统计到 ${file}..." # 使用 curl 同时获取响应体和 HTTP 状态码 RESPONSE=$(curl -sS -w "\n%{http_code}" -H "${AUTH_HEADER}" "${API_BASE}/usage/export") HTTP_CODE=$(echo "${RESPONSE}" | tail -n1) BODY=$(echo "${RESPONSE}" | sed '$d') if [[ "${HTTP_CODE}" != "200" ]]; then echo "导出失败 (HTTP ${HTTP_CODE}): ${BODY}" return 1 fi echo "${BODY}" > "${file}" echo "导出完成: ${file}" } # ------------------------------------------------------------ # 子命令:import # 功能:从 stats 目录中“最新的” usage-*.json 备份文件中导入使用统计 # 用法:./upgrade.sh import # 场景:升级后、迁移后,需要把使用统计恢复回来 # ------------------------------------------------------------ import_latest_usage() { local latest latest="$(ls -1t "${STATS_DIR}"/usage-*.json 2>/dev/null | head -n 1 || true)" if [[ -z "${latest}" ]]; then echo "没有找到可用的使用统计备份,跳过导入。" return 0 fi echo "导入最近一次的使用统计:${latest} ..." RESPONSE=$(curl -sS -w "\n%{http_code}" -X POST \ -H "${AUTH_HEADER}" \ -H "Content-Type: application/json" \ -d @"${latest}" \ "${API_BASE}/usage/import") HTTP_CODE=$(echo "${RESPONSE}" | tail -n1) BODY=$(echo "${RESPONSE}" | sed '$d') if [[ "${HTTP_CODE}" == "200" ]]; then echo "导入完成。" else echo "导入失败 (HTTP ${HTTP_CODE}): ${BODY}" return 1 fi } # ------------------------------------------------------------ # 辅助函数:等待 CLIProxyAPI 服务启动并能正常响应 HTTP 200 # 在 upgrade 流程中用于“拉起容器后等待后端真正就绪” # ------------------------------------------------------------ wait_for_server() { echo "等待 CLIProxyAPI 启动..." for _ in $(seq 1 60); do if curl -sS -o /dev/null -w "%{http_code}" "http://${HOST}:${PORT}/" 2>/dev/null | grep -q "200"; then echo "服务已就绪。" return 0 fi sleep 2 done echo "等待服务超时,请检查容器是否正常启动。" >&2 return 1 } # ------------------------------------------------------------ # 子命令:upgrade (一键升级) # # 完整流程: # 1. 导出当前使用统计(避免升级丢数据) # 2. 使用 docker compose 拉取最新镜像并重启 cli-proxy-api 容器 # 3. 等待 CLIProxyAPI HTTP 服务就绪 # 4. 从刚刚导出的备份中重新导入使用统计 # # 用法:./upgrade.sh upgrade # ------------------------------------------------------------ upgrade() { echo "=== 步骤 1:导出当前使用统计 ===" export_usage echo "=== 步骤 2:检查并拉取最新镜像 ===" cd "${BASE_DIR}" # 获取当前容器使用的镜像名称(从 docker-compose.yml 解析或从运行中的容器获取) # 优先从运行中的容器获取,如果没有运行则从 docker-compose config 解析 if docker ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then # 容器正在运行,从容器获取镜像名 current_image=$(docker inspect --format='{{.Config.Image}}' "${CONTAINER_NAME}" 2>/dev/null || true) else # 容器未运行,从 docker-compose config 解析镜像名 current_image=$(docker compose config --format json 2>/dev/null | grep -o '"image":"[^"]*"' | head -1 | cut -d'"' -f4 || true) fi if [[ -z "${current_image}" ]]; then echo "警告:无法确定当前镜像名称,将强制拉取并重启。" >&2 current_image="unknown" else echo "当前使用的镜像:${current_image}" # 获取 pull 前的镜像 ID(如果镜像存在) image_id_before=$(docker image inspect "${current_image}" --format='{{.Id}}' 2>/dev/null || echo "") fi # 执行 pull echo "正在拉取最新镜像..." if ! docker compose pull "${CONTAINER_NAME}"; then echo "拉取镜像失败,请检查 docker compose 配置和网络。" >&2 return 1 fi # 获取 pull 后的镜像 ID if [[ "${current_image}" != "unknown" ]]; then image_id_after=$(docker image inspect "${current_image}" --format='{{.Id}}' 2>/dev/null || echo "") # 如果 pull 前后镜像 ID 相同,说明没有新镜像 if [[ -n "${image_id_before}" && -n "${image_id_after}" && "${image_id_before}" == "${image_id_after}" ]]; then echo "检测到镜像已是最新版本(镜像 ID 未变化),本次无需升级容器,后续步骤(重启 / 导入)将跳过。" echo "=== 升级流程结束(无新镜像,无需变更) ===" return 0 fi fi echo "检测到有新镜像或镜像已更新,继续执行容器重启和数据导入。" echo "=== 步骤 3:重启容器 ===" docker compose stop "${CONTAINER_NAME}" || true docker compose up -d "${CONTAINER_NAME}" echo "=== 步骤 4:等待服务就绪 ===" wait_for_server echo "=== 步骤 5:导入使用统计 ===" import_latest_usage echo "=== 升级流程完成 ===" } # ========= 命令行入口 ========= # 如果你想“无参数就默认执行 upgrade”,可以把下面的 "${1:-}" 改成: # cmd="${1:-upgrade}" # 然后把 case 的变量改成 "${cmd}" 即可。 # # 当前版本设计为“必须显式传入子命令”,这样更安全,不容易误操作。 case "${1:-}" in export) export_usage ;; import) import_latest_usage ;; upgrade) upgrade ;; *) echo "用法: $0 {export|import|upgrade}" >&2 echo echo "说明:" echo " export 只导出当前使用统计到 stats 目录" echo " import 只从最近的 usage-*.json 备份文件中导入使用统计" echo " upgrade 先导出,再升级容器,最后导入(推荐用于升级系统)" exit 1 ;; esac 网友解答:


--【壹】--:

不客气


--【贰】--:

这个功能好


--【叁】--:

好样的,回头试试看


--【肆】--:

正好用上,我也一直每天凌晨用脚本自动更新,但数据全丢了,现在好了


--【伍】--:

哇,感谢大佬


--【陆】--:

可以很实用


--【柒】--:

谢谢大佬,刚刚重启了,数据全没了,好多了


--【捌】--:

感谢大佬


--【玖】--:

感谢大佬


--【拾】--:

谢谢大佬,正好要用到,认证文件能保留吗


--【拾壹】--:

感谢大佬


--【拾贰】--:

mark一记,谢谢佬


--【拾叁】--:

同,回头试试


--【拾肆】--:

是的,心痛ing 虽然可能是小众需求 暂时顶顶用着