auto-sync: 2026-05-14 10:20:01
This commit is contained in:
267
tasks/claude-cli-proxy/DEV_TASK.md
Normal file
267
tasks/claude-cli-proxy/DEV_TASK.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# DEV TASK: Деплой CLIProxyAPI на mva154
|
||||
|
||||
**Статус:** Ready for dev
|
||||
**Проект:** claude-cli-proxy
|
||||
**BRD:** `tasks/claude-cli-proxy/BRD.md`
|
||||
|
||||
---
|
||||
|
||||
## Цель
|
||||
|
||||
Поднять CLIProxyAPI в Docker на mva154, подготовить к OAuth авторизации Claude Max подписки. После авторизации — OpenClaw сможет использовать Claude через подписку вместо API токенов.
|
||||
|
||||
## Контекст
|
||||
|
||||
- **CLIProxyAPI** — Go-сервер, оборачивает Claude Code CLI в OpenAI-compatible API
|
||||
- **Docker image:** `eceasy/cli-proxy-api:latest`
|
||||
- **Порт по умолчанию:** 8317
|
||||
- **OAuth порт (для логина):** 54545
|
||||
- **Доступ:** только из docker network (OpenClaw контейнер на том же хосте)
|
||||
- **Один аккаунт**, без load balancing
|
||||
|
||||
---
|
||||
|
||||
## Инфраструктура
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| Сервер | `slin@82.22.50.71` (пароль: `motoZ@yaz2010`) |
|
||||
| SSH | через Node.js ssh2 модуль |
|
||||
| Docker network | та же сеть что у OpenClaw контейнера |
|
||||
| Рабочая директория | `/home/slin/claude-cli-proxy/` |
|
||||
|
||||
---
|
||||
|
||||
## Задачи
|
||||
|
||||
### Task 1: Подготовка файлов на сервере
|
||||
|
||||
**Шаги:**
|
||||
|
||||
- [ ] **1.1** Создать директорию и config.yaml:
|
||||
|
||||
```bash
|
||||
mkdir -p /home/slin/claude-cli-proxy/auth
|
||||
cat > /home/slin/claude-cli-proxy/config.yaml << 'EOF'
|
||||
port: 8317
|
||||
remote-management:
|
||||
allow-remote: false
|
||||
secret-key: ""
|
||||
auth-dir: "/root/.cli-proxy-api"
|
||||
auth:
|
||||
providers: []
|
||||
debug: false
|
||||
EOF
|
||||
```
|
||||
|
||||
Примечание: `auth.providers: []` — отключает проверку API key, используется OAuth токен.
|
||||
|
||||
- [ ] **1.2** Создать docker-compose.yml:
|
||||
|
||||
```bash
|
||||
cat > /home/slin/claude-cli-proxy/docker-compose.yml << 'EOF'
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
cli-proxy-api:
|
||||
image: eceasy/cli-proxy-api:latest
|
||||
container_name: claude-cli-proxy
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:8317:8317"
|
||||
volumes:
|
||||
- ./config.yaml:/CLIProxyAPI/config.yaml
|
||||
- ./auth:/root/.cli-proxy-api
|
||||
networks:
|
||||
- openclaw_net
|
||||
|
||||
networks:
|
||||
openclaw_net:
|
||||
external: true
|
||||
EOF
|
||||
```
|
||||
|
||||
⚠️ **ВАЖНО:** Нужно узнать имя docker network где живёт OpenClaw контейнер. Проверить:
|
||||
```bash
|
||||
docker network ls
|
||||
docker inspect <openclaw-container-name> --format '{{range .NetworkSettings.Networks}}{{.NetworkID}}{{end}}'
|
||||
```
|
||||
|
||||
Заменить `openclaw_net` на реальное имя сети.
|
||||
|
||||
- [ ] **1.3** Проверить что image скачивается:
|
||||
|
||||
```bash
|
||||
cd /home/slin/claude-cli-proxy
|
||||
docker compose pull
|
||||
```
|
||||
|
||||
**Критерий:** Файлы на месте, image скачан.
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Первый запуск и OAuth авторизация
|
||||
|
||||
**Шаги:**
|
||||
|
||||
- [ ] **2.1** Запустить контейнер в режиме логина (одноразово):
|
||||
|
||||
```bash
|
||||
cd /home/slin/claude-cli-proxy
|
||||
docker run --rm -it \
|
||||
-p 54545:54545 \
|
||||
-v $(pwd)/config.yaml:/CLIProxyAPI/config.yaml \
|
||||
-v $(pwd)/auth:/root/.cli-proxy-api \
|
||||
eceasy/cli-proxy-api:latest \
|
||||
/CLIProxyAPI/CLIProxyAPI --claude-login --no-browser
|
||||
```
|
||||
|
||||
Это выведет URL для авторизации. **Этот URL нужно передать Славе** — он откроет его в браузере и залогинится.
|
||||
|
||||
⚠️ Флаг `--no-browser` обязателен (headless сервер, нет GUI).
|
||||
|
||||
- [ ] **2.2** После успешного логина — проверить что токен сохранился:
|
||||
|
||||
```bash
|
||||
ls -la /home/slin/claude-cli-proxy/auth/
|
||||
# Должен быть файл с OAuth credentials
|
||||
```
|
||||
|
||||
**Критерий:** OAuth токен сохранён в `./auth/`.
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Запуск сервиса
|
||||
|
||||
**Шаги:**
|
||||
|
||||
- [ ] **3.1** Запустить через docker-compose:
|
||||
|
||||
```bash
|
||||
cd /home/slin/claude-cli-proxy
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
- [ ] **3.2** Проверить что контейнер работает:
|
||||
|
||||
```bash
|
||||
docker ps | grep claude-cli-proxy
|
||||
docker logs claude-cli-proxy --tail 20
|
||||
```
|
||||
|
||||
- [ ] **3.3** Проверить API:
|
||||
|
||||
```bash
|
||||
# Список моделей
|
||||
curl -s http://127.0.0.1:8317/v1/models | python3 -m json.tool
|
||||
|
||||
# Тестовый запрос
|
||||
curl -s -X POST http://127.0.0.1:8317/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer dummy" \
|
||||
-d '{
|
||||
"model": "claude-sonnet-4-20250514",
|
||||
"messages": [{"role": "user", "content": "Say hello, one sentence only"}],
|
||||
"stream": false
|
||||
}' | python3 -m json.tool
|
||||
```
|
||||
|
||||
- [ ] **3.4** Проверить streaming:
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:8317/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer dummy" \
|
||||
-d '{
|
||||
"model": "claude-sonnet-4-20250514",
|
||||
"messages": [{"role": "user", "content": "Count from 1 to 5"}],
|
||||
"stream": true
|
||||
}'
|
||||
# Должен выдавать SSE chunks
|
||||
```
|
||||
|
||||
**Критерий:** API отвечает, streaming работает.
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Подключение к docker network OpenClaw
|
||||
|
||||
**Шаги:**
|
||||
|
||||
- [ ] **4.1** Определить сеть OpenClaw:
|
||||
|
||||
```bash
|
||||
# Найти контейнер OpenClaw
|
||||
docker ps | grep -i openclaw
|
||||
# Посмотреть его сеть
|
||||
docker inspect <container_name> --format '{{json .NetworkSettings.Networks}}' | python3 -m json.tool
|
||||
```
|
||||
|
||||
- [ ] **4.2** Обновить docker-compose.yml с правильным именем сети (если отличается от `openclaw_net`)
|
||||
|
||||
- [ ] **4.3** Проверить что OpenClaw контейнер видит прокси:
|
||||
|
||||
```bash
|
||||
# Из контейнера OpenClaw
|
||||
docker exec <openclaw-container> curl -s http://claude-cli-proxy:8317/v1/models
|
||||
```
|
||||
|
||||
**Критерий:** OpenClaw контейнер может достучаться до `claude-cli-proxy:8317`.
|
||||
|
||||
---
|
||||
|
||||
## Проверка (Acceptance)
|
||||
|
||||
| # | Проверка | Команда | Ожидаемый результат |
|
||||
|---|----------|---------|---------------------|
|
||||
| 1 | Контейнер запущен | `docker ps \| grep claude-cli-proxy` | STATUS: Up |
|
||||
| 2 | Models endpoint | `curl http://127.0.0.1:8317/v1/models` | JSON с claude моделями |
|
||||
| 3 | Chat completion | `curl POST /v1/chat/completions` | Ответ от Claude |
|
||||
| 4 | Streaming | `curl POST stream=true` | SSE chunks |
|
||||
| 5 | Доступ из OpenClaw | `docker exec openclaw curl ...` | Ответ от прокси |
|
||||
|
||||
---
|
||||
|
||||
## Ограничения и грабли
|
||||
|
||||
- ⚠️ SSH только через Node.js ssh2 (бинарный ssh сломан в контейнере OpenClaw)
|
||||
- ⚠️ OAuth логин — **ручной шаг**, нужен браузер Славы. Dev готовит URL, Слава логинится.
|
||||
- ⚠️ `--no-browser` обязателен при логине (headless сервер)
|
||||
- ⚠️ `auth.providers: []` в config — без этого будет требовать API key
|
||||
- ⚠️ Порт 8317 слушает только на 127.0.0.1 (не наружу!)
|
||||
- ⚠️ Имя docker network нужно определить динамически — не хардкодить
|
||||
- 🚫 НЕ открывать порт наружу
|
||||
- 🚫 НЕ запускать несколько инстансов (риск бана)
|
||||
|
||||
---
|
||||
|
||||
## После деплоя (делает Стрим, не Dev)
|
||||
|
||||
После успешного Task 4 — Стрим добавит provider в OpenClaw config:
|
||||
```json
|
||||
{
|
||||
"id": "claude-cli-proxy",
|
||||
"type": "openai",
|
||||
"baseUrl": "http://claude-cli-proxy:8317/v1",
|
||||
"apiKey": "dummy",
|
||||
"models": ["claude-sonnet-4-20250514", "claude-opus-4-20250514"]
|
||||
}
|
||||
```
|
||||
|
||||
И назначит Dev-агенту модель через этот provider.
|
||||
|
||||
---
|
||||
|
||||
## Деплой-чеклист
|
||||
|
||||
- [ ] Директория и файлы созданы
|
||||
- [ ] Docker image скачан
|
||||
- [ ] OAuth авторизация пройдена (ручной шаг Славы)
|
||||
- [ ] Контейнер запущен и отвечает
|
||||
- [ ] Streaming работает
|
||||
- [ ] Доступен из docker network OpenClaw
|
||||
- [ ] Порт НЕ открыт наружу
|
||||
|
||||
---
|
||||
|
||||
*Создано: 2026-05-14 | Автор ТЗ: Стрим | Исполнитель: Dev-агент*
|
||||
Reference in New Issue
Block a user