Files
2026-11-05 14:10:48 +08:00

130 lines
4.4 KiB
Bash

#!/usr/bin/env bash
# ==========================================================
# CPA (CLIProxyAPI) one-click deploy script
# Target : Tencent SG server ubuntu@43.156.118.130
# Effect : create /opt/cpa + start cli-proxy-api container
# existing new-api / nginx / xray are NOT modified
# (only a runtime docker network attach for new-api)
# Idempotent: safe to run multiple times.
# Run as root: sudo bash deploy-cpa.sh
# ==========================================================
set -euo pipefail
step() { echo ""; echo "========== [$1] $2 =========="; }
step 1 "Pre-check"
[ "$(id -u)" -eq 0 ] || { echo "ERROR: run as root (sudo bash)"; exit 1; }
docker ps --format ' {{.Names}} | {{.Status}}'
step 2 "Create /opt/cpa"
mkdir -p /opt/cpa/auths /opt/cpa/logs /opt/cpa/plugins
cd /opt/cpa
step 3 "Generate config.yaml (keep existing if present)"
if [ -f config.yaml ]; then
echo " config.yaml exists, keep it"
else
CPA_API_KEY="sk-cpa-$(openssl rand -hex 16)"
MGMT_KEY="$(openssl rand -hex 16)"
cat > config.yaml <<EOF
config-version: 8
server:
host: "" # bind all ifaces INSIDE container; exposure controlled by compose loopback binding
port: 8317
management:
allow-remote: false # panel reachable only via localhost / ssh tunnel
secret-key: "${MGMT_KEY}"
access:
api-keys:
- "${CPA_API_KEY}" # used by New API channel
oauth:
auth-dir: "~/.cli-proxy-api"
observability:
usage:
usage-statistics-enabled: true
EOF
chmod 600 config.yaml
cat > KEYS.txt <<EOF
# ============================================
# CPA secrets (keep private)
# Management panel key (MGMT_KEY):
${MGMT_KEY}
# API key for New API channel (CPA_API_KEY):
${CPA_API_KEY}
# ============================================
EOF
chmod 600 KEYS.txt
echo " config.yaml + KEYS.txt generated"
fi
step 4 "Write docker-compose.yml"
cat > docker-compose.yml <<'EOF'
services:
cli-proxy-api:
image: eceasy/cli-proxy-api:latest
container_name: cli-proxy-api
restart: unless-stopped
ports:
# all bound to server loopback only -> NOT reachable from public internet
# 8317 = API + management panel, others = OAuth callback ports per provider
- "127.0.0.1:8317:8317"
- "127.0.0.1:8085:8085"
- "127.0.0.1:1455:1455"
- "127.0.0.1:54545:54545"
- "127.0.0.1:51121:51121" # Antigravity OAuth callback
- "127.0.0.1:11451:11451"
volumes:
- ./config.yaml:/CLIProxyAPI/config.yaml
- ./auths:/root/.cli-proxy-api
- ./logs:/CLIProxyAPI/logs
- ./plugins:/CLIProxyAPI/plugins
networks:
- ai-net
networks:
ai-net:
external: true
EOF
echo " done"
step 5 "Docker network ai-net (shared with new-api)"
docker network inspect ai-net >/dev/null 2>&1 || docker network create ai-net
docker network connect ai-net new-api 2>/dev/null && echo " new-api joined ai-net" || echo " new-api already in ai-net (or not running)"
step 6 "Start container"
docker compose up -d
sleep 6
docker ps --filter name=cli-proxy-api --format ' {{.Names}} | {{.Status}} | {{.Ports}}'
step 7 "Verify"
CPA_API_KEY=$(grep -oE 'sk-cpa-[0-9a-f]+' config.yaml | head -1 || true)
[ -n "$CPA_API_KEY" ] || { echo "ERROR: api key not found in config.yaml"; exit 1; }
echo "-- no key (expect 401):"
curl -s -o /dev/null -w ' HTTP %{http_code}\n' http://127.0.0.1:8317/v1/models
echo "-- with key (expect 200; model list may be empty before OAuth login):"
curl -s -w '\n HTTP %{http_code}\n' http://127.0.0.1:8317/v1/models -H "Authorization: Bearer ${CPA_API_KEY}" | head -c 400
echo ""
echo "-- new-api container -> cli-proxy-api connectivity:"
if docker exec new-api sh -c 'command -v curl' >/dev/null 2>&1; then
docker exec new-api sh -c "curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://cli-proxy-api:8317/v1/models" | sed 's/^/ HTTP /'
echo " (any HTTP code = network OK)"
elif docker exec new-api sh -c 'command -v wget' >/dev/null 2>&1; then
docker exec new-api sh -c "wget -S -q -O /dev/null http://cli-proxy-api:8317/v1/models 2>&1 | head -1" | sed 's/^/ /'
else
echo " no curl/wget inside new-api, skip (use New API channel test later)"
fi
echo ""
echo "=========================================================="
echo " DEPLOY DONE. Secrets (also saved at /opt/cpa/KEYS.txt):"
echo "=========================================================="
cat KEYS.txt
echo ""
echo "Next: open tunnel.bat locally, then visit"
echo " http://localhost:8317/management.html"