Ai

CLI-Proxy-API

上传于 2026年3月14日13 个章节

CLI-Proxy-API

13 个章节

CLIProxyAPI 的 Docker Compose 部署、管理接口保护、更新及统计数据备份恢复。

  • #CLIProxyAPI
  • #Docker
  • #运维
  • #API

介绍

  • 无需安装 Gemini CLI,即可将其授权转换为通用的 API Key,从而在任何应用中调用功能完整的 Gemini 2.5 Pro、Gemini 2.5 Flash、Gemini 2.5 Flash Lite 模型。当正式版模型配额用尽后,它会自动切换到 Preview 模型(如 gemini-2.5-pro-preview-05-06),基本能用足每天 1000 次的调用配额,轻松实现“Gemini 自由”。
  • 无需安装 Qwen Code,即可将其授权转换为通用的 API Key,在任何地方调用 Qwen3 Coder Plus、Qwen3 Coder Flash 模型,实现“Qwen3 Coder 自由”。
  • 无需安装 Codex,即可将其授权转换为通用的 API Key,在任何地方调用 GPT-5、GPT-5-Codex 模型。尤其在目前可以免费开设 Team 账户的活动下,轻松实现“GPT 自由”。
  • 将 Gemini 网页版转换为 API Key,在任何地方调用 Nano Banana 等网页版模型(需客户端支持。据网友分享,免费版 Gemini 网页账户每天可调用约 100 次,而 Gemini Pro 用户则高达 1000 次)。
  • 强大的负载均衡能力。CLIProxyAPI 支持将不同来源(无论是 API Key 还是 OAuth 授权)的多个账户整合在一起进行负载均衡轮询,这意味着你可以轻松地将调用配额翻倍。
  • 极低的资源消耗。值得一提的是,该程序对系统资源的消耗极低。程序本身仅 10MB 左右,启动时内存占用不到 10MB,长时间峰值内存占用也仅有 100MB 左右,几乎任何电脑都能流畅运行。

docker compost部署

1.创建目录和配置文件

mkdir -p /data/CLIProxyAPI && touch /data/CLIProxyAPI/config.yaml

2.修改配置文件

# Server host/interface to bind to. Default is empty ("") to bind all interfaces (IPv4 + IPv6).
# Use "127.0.0.1" or "localhost" to restrict access to local machine only.
host: ""
# Server port
port: 8317
# TLS settings for HTTPS. When enabled, the server listens with the provided certificate and key.
tls:
  enable: false
  cert: ""
  key: ""
# Management API settings
remote-management:
# Whether to allow remote (non-localhost) management access.
# When false, only localhost can access management endpoints (a key is still required).
  allow-remote: true
# Management key. If a plaintext value is provided here, it will be hashed on startup.
# All management requests (even from localhost) require this key.
# Leave empty to disable the Management API entirely (404 for all /v0/management routes).
  secret-key: "REPLACE_WITH_STRONG_SECRET"
# Disable the bundled management control panel asset download and HTTP route when true.
  disable-control-panel: false
# GitHub repository for the management control panel. Accepts a repository URL or releases API URL.
  panel-github-repository: "https://github.com/router-for-me/Cli-Proxy-API-Management-Center"
# Authentication directory (supports ~ for home directory)
auth-dir: "~/.cli-proxy-api"

3.运行 mkdir -p /data/CLIProxyAPI && touch /data/CLIProxyAPI/compose.yaml ,创建 docker compose 文件,并配置

services:
  cli-proxy-api:
    image: eceasy/cli-proxy-api:latest
    container_name: cli-proxy-api
    ports:
      - "8317:8317"
    volumes:
      - ./config.yaml:/CLIProxyAPI/config.yaml
      - ./auths:/root/.cli-proxy-api
    restart: unless-stopped

4.运行命令 cd /data/CLIProxyAPI && docker compose up -d ,创建容器

5.访问:服务器IP:8317/management.html

webUI启动

注意: WebUI 中的 OAuth 认证功能仅支持本地运行(例如 localhost 或 127.0.0.1)的 CLIProxyAPI 实例。对于部署在远程服务器上的实例,由于 OAuth 服务商的安全策略限制,将无法通过 WebUI 直接完成认证。

访问页面http://localhost:8317/management.html#/ `

更新cpa

最稳的更新流程:

1.先导出统计数据 用面板里的“导出”按钮,或者先备份一份导出文件。

2.备份配置 建议至少备份这几个: -
/data/CLIProxyAPI/.env
/data/CLIProxyAPI/config.yaml
/data/CLIProxyAPI/auths/
/data/CLIProxyAPI/compose.yaml

3.拉新镜像并重建主容器

cd /data/CLIProxyAPI

docker pull eceasy/cli-proxy-api:latest

docker compose up -d --force-recreate cli-proxy-api

4.检查是否启动成功
docker ps | grep cli-proxy-api
docker logs --tail 100 cli-proxy-api

5.登录面板确认版本和统计

自动更新 + 备份恢复

CPA 可以用 watchtower 做镜像自动更新,并配合生命周期钩子在更新前导出统计数据、更新后再导入统计数据。这样更新容器时,运行态统计数据可以先保存到宿主机目录,容器重建完成后再恢复。

自动更新配置

核心服务仍然由 compose.yaml 管理,watchtower 负责定时检查镜像:

watchtower:
  image: nickfedor/watchtower:latest
  container_name: watchtower
  restart: always
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  environment:
    TZ: Asia/Shanghai
    WATCHTOWER_CLEANUP: "true"
    WATCHTOWER_POLL_INTERVAL: "3600"
    WATCHTOWER_SCOPE: "cliproxy"
    WATCHTOWER_LIFECYCLE_HOOKS: "true"
  command: --scope cliproxy

业务容器需要加上相同的 scope 标签,并配置更新前、更新后的钩子:

labels:
  - "com.centurylinklabs.watchtower.scope=cliproxy"
  - "com.centurylinklabs.watchtower.lifecycle.pre-update=/bin/sh -c 'curl -sf -H \"Authorization: Bearer ${MANAGEMENT_PASSWORD}\" http://localhost:8317/v0/management/usage/export -o /CLIProxyAPI/persist/usage-backup.json.tmp && test -s /CLIProxyAPI/persist/usage-backup.json.tmp && mv /CLIProxyAPI/persist/usage-backup.json.tmp /CLIProxyAPI/persist/usage-backup.json || { rm -f /CLIProxyAPI/persist/usage-backup.json.tmp; exit 1; }'"
  - "com.centurylinklabs.watchtower.lifecycle.post-update=/bin/sh -c 'sleep 3 && test -s /CLIProxyAPI/persist/usage-backup.json && curl -sf -X POST -H \"Content-Type: application/json\" -H \"Authorization: Bearer ${MANAGEMENT_PASSWORD}\" --data-binary @/CLIProxyAPI/persist/usage-backup.json http://localhost:8317/v0/management/usage/import'"

这里更新前先写入 .tmp 临时文件,确认导出成功且文件非空后,再替换正式备份文件。这样可以避免导出失败时把旧备份清空。

MANAGEMENT_PASSWORD 来自 /data/CLIProxyAPI/.env 或执行 docker compose 时所在 Shell 的环境变量。docker compose 读取 compose.yaml 时会把 ${MANAGEMENT_PASSWORD} 替换成实际值,然后写入容器标签和容器环境变量。watchtower 执行生命周期钩子时,标签里的命令已经带有实际管理密码,所以 Authorization: Bearer ${MANAGEMENT_PASSWORD} 最终会变成真实密码。

可以用下面命令确认容器环境变量中存在该值,输出时注意不要把明文密码贴到公开位置:

docker inspect cli-proxy-api --format '{{range .Config.Env}}{{println .}}{{end}}' | grep '^MANAGEMENT_PASSWORD='

手动备份脚本

手动备份脚本放在:

/data/CLIProxyAPI/backup-usage.sh

用途是调用管理接口导出统计数据,保存到:

/data/CLIProxyAPI/usage-backup/

执行方式:

cd /data/CLIProxyAPI
./backup-usage.sh

脚本逻辑:

1. 从当前容器环境变量读取 MANAGEMENT_PASSWORD。
2. 调用 /v0/management/usage/export 导出统计数据。
3. 先写入临时文件,确认文件非空且 JSON 有效。
4. 校验通过后保存为带时间戳的备份文件。
5. 默认保留最近 10 份备份。

脚本内容:

#!/bin/bash
set -u

BASE_DIR="/data/CLIProxyAPI"
BACKUP_DIR="${BACKUP_DIR:-$BASE_DIR/usage-backup}"
KEEP_COUNT="${KEEP_COUNT:-10}"
CONTAINER_NAME="${CONTAINER_NAME:-cli-proxy-api}"
PORT="${PORT:-8317}"
BACKUP_NAME="${BACKUP_NAME:-instance1}"
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"

mkdir -p "$BACKUP_DIR"

get_management_password() {
  docker inspect "$CONTAINER_NAME" --format '{{range .Config.Env}}{{println .}}{{end}}' \
    | awk -F= '/^MANAGEMENT_PASSWORD=/{print substr($0, index($0, "=") + 1); exit}'
}

validate_json() {
  local file="$1"
  python3 -m json.tool "$file" >/dev/null 2>&1
}

management_password="$(get_management_password)"
if [ -z "$management_password" ]; then
  echo "[ERR] 未读取到 MANAGEMENT_PASSWORD"
  exit 1
fi

output_file="$BACKUP_DIR/${BACKUP_NAME}_${TIMESTAMP}.json"
temp_file="${output_file}.tmp"

if curl -sf \
    -H "Authorization: Bearer ${management_password}" \
    "http://127.0.0.1:${PORT}/v0/management/usage/export" \
    -o "$temp_file" \
    && [ -s "$temp_file" ] \
    && validate_json "$temp_file"; then
  mv "$temp_file" "$output_file"
  echo "[OK] 备份成功: $output_file"
  ls -t "$BACKUP_DIR/${BACKUP_NAME}_"*.json 2>/dev/null | tail -n +$((KEEP_COUNT + 1)) | xargs -r rm -f
  exit 0
fi

rm -f "$temp_file"
echo "[ERR] 备份失败"
exit 1

手动恢复脚本

恢复脚本放在:

/data/CLIProxyAPI/restore-usage.sh

执行方式:

cd /data/CLIProxyAPI
./restore-usage.sh

脚本会查找最新的统计备份文件,恢复前先检查文件是否存在、是否为空、JSON 是否有效,然后等待管理接口可访问,再调用:

/v0/management/usage/import

恢复脚本会改动当前统计数据,执行前需要确认最新备份文件就是预期恢复版本。

脚本内容:

#!/bin/bash
set -u

BASE_DIR="/data/CLIProxyAPI"
BACKUP_DIR="${BACKUP_DIR:-$BASE_DIR/usage-backup}"
CONTAINER_NAME="${CONTAINER_NAME:-cli-proxy-api}"
PORT="${PORT:-8317}"
BACKUP_NAME="${BACKUP_NAME:-instance1}"

get_management_password() {
  docker inspect "$CONTAINER_NAME" --format '{{range .Config.Env}}{{println .}}{{end}}' \
    | awk -F= '/^MANAGEMENT_PASSWORD=/{print substr($0, index($0, "=") + 1); exit}'
}

validate_json() {
  local file="$1"
  python3 -m json.tool "$file" >/dev/null 2>&1
}

wait_until_ready() {
  local management_password="$1"

  for i in $(seq 1 15); do
    if curl -sf \
        -H "Authorization: Bearer ${management_password}" \
        "http://127.0.0.1:${PORT}/v0/management/usage" \
        >/dev/null 2>&1; then
      return 0
    fi
    echo "[WAIT] 等待接口就绪 $i/15"
    sleep 2
  done

  return 1
}

latest_file="$(ls -t "$BACKUP_DIR/${BACKUP_NAME}_"*.json 2>/dev/null | head -1 || true)"
if [ -z "$latest_file" ]; then
  echo "[SKIP] 未找到备份文件"
  exit 0
fi

if [ ! -s "$latest_file" ]; then
  echo "[ERR] 备份文件为空: $latest_file"
  exit 1
fi

if ! validate_json "$latest_file"; then
  echo "[ERR] 备份文件 JSON 无效: $latest_file"
  exit 1
fi

management_password="$(get_management_password)"
if [ -z "$management_password" ]; then
  echo "[ERR] 未读取到 MANAGEMENT_PASSWORD"
  exit 1
fi

if ! wait_until_ready "$management_password"; then
  echo "[ERR] 接口未就绪"
  exit 1
fi

if curl -sf -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${management_password}" \
    --data-binary "@$latest_file" \
    "http://127.0.0.1:${PORT}/v0/management/usage/import" \
    >/dev/null; then
  echo "[OK] 恢复成功: $latest_file"
  exit 0
fi

echo "[ERR] 恢复失败: $latest_file"
exit 1

检查命令

脚本语法检查:

cd /data/CLIProxyAPI
bash -n backup-usage.sh
bash -n restore-usage.sh

compose.yaml 配置检查:

docker compose -f compose.yaml config

执行备份并检查文件:

./backup-usage.sh
ls -lh usage-backup
python3 -m json.tool usage-backup/instance1_*.json >/dev/null

查看容器和自动更新服务:

docker ps --format 'table {{.Names}}	{{.Status}}	{{.Ports}}'
docker logs --tail 100 watchtower

qwen授权

配置qwen-cli进行测试

完成登录后去到 cherry-studio 中配置, 提供商类型选择 openAi

完成测试

有点牛逼, 但是太多了, 我用不过来, 仅记录一下

codex授权

登录403的问题本质上cliproxy在终端环节中运行的, 需要设置代理

设置代理后即可登录

添加模型

验证一下

开启tun模式后 就正常了, 那么这里不使用tun模式的话有什么办法呢?

iflow授权

cookie登录

因为在配置codex时不想开tun, 所以配置了proxifier 中 cliProxyApi走代理 any主机, 所以导致iflow登录页走了代理失败 通过配置cliProxyApi的规则openai走代理就可以了

chatgpt.com; *.chatgpt.com; api.openai.com; *.openai.com

iflow glm4.7 测试

使用codex 打通cpa 和 new api

1.登录cpa 通过 OAuth进行 codex登录, 点击链接完成登录,等完成后页面报错不要紧,复制链接到cpa进行认证, 自动保存认证文件

2.在配置面板 api密钥处添加密钥 3.回到new api添加渠道,api就是cpa的IP端口, 密钥是cpa的密钥

4.测试, 选择流式输出 注意:

  1. cpa不可以进行分组, 会将所有认证文件全部接入 new api, 然后在new api中获取模型列表进行选择
  2. 现有两种类型账号在cpa中,通过new api请求的话,会在cpa中进行切换模型

搜索文章与随记

输入关键词搜索全部公开内容