docs: add infrastructure plan and Claude agent guide
- infrastructure-plan.md: server resource analysis (1 vCPU / 2GB RAM critically overloaded), two-server architecture recommendation - claude-agent.md: how to run Claude Code as an autonomous infra agent via Anthropic API + Telegram bot interface Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
efbbc3cac5
commit
9e4ac718d9
2 changed files with 352 additions and 0 deletions
225
docs/claude-agent.md
Normal file
225
docs/claude-agent.md
Normal file
|
|
@ -0,0 +1,225 @@
|
||||||
|
# Claude Code Agent на сервере
|
||||||
|
|
||||||
|
Это руководство объясняет как запустить Claude Code как автономного агента на сервере, который будет управлять инфраструктурой без участия человека.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что это такое
|
||||||
|
|
||||||
|
**Claude Code** — CLI-инструмент от Anthropic, тот самый с которым ты сейчас работаешь. Его можно запустить на сервере в режиме автономного агента. Агент:
|
||||||
|
|
||||||
|
- Имеет доступ к файлам репозитория
|
||||||
|
- Может запускать shell-команды (Ansible, Docker, Git)
|
||||||
|
- Слушает задачи через API и выполняет их
|
||||||
|
- Работает в рамках твоей подписки Anthropic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Два режима работы
|
||||||
|
|
||||||
|
### Режим 1: "Разбуди и сделай" (простой)
|
||||||
|
|
||||||
|
Ты пишешь задачу (в Telegram боте, через web-форму, вручную) → скрипт запускает Claude Code с этой задачей → Claude делает → результат тебе.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск задачи вручную
|
||||||
|
claude --print "Задача: обнови Forgejo до последней версии, протестируй, задеплой" \
|
||||||
|
--allowedTools "Bash,Read,Edit,Write,Glob,Grep"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Режим 2: Постоянный агент (сложнее)
|
||||||
|
|
||||||
|
Claude Code запущен как сервис, слушает очередь задач (через Redis или простой API).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что нужно купить / активировать
|
||||||
|
|
||||||
|
### Вариант A: Claude.ai Pro или Max (подписка)
|
||||||
|
|
||||||
|
- **Цена:** Pro $20/мес, Max $100/мес
|
||||||
|
- **Что даёт:** Claude Code работает через OAuth с вашим аккаунтом
|
||||||
|
- **Лимиты:** зависят от тарифа, при интенсивном использовании могут кончаться
|
||||||
|
- **Подходит для:** редких задач, человек инициирует каждую задачу
|
||||||
|
|
||||||
|
**Авторизация на сервере:**
|
||||||
|
```bash
|
||||||
|
# Установка
|
||||||
|
npm install -g @anthropic-ai/claude-code
|
||||||
|
|
||||||
|
# Авторизация (один раз, браузер не нужен — используй --print с токеном)
|
||||||
|
claude auth login
|
||||||
|
# Или через переменную среды:
|
||||||
|
export ANTHROPIC_API_KEY=sk-ant-...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Вариант B: Anthropic API Key (рекомендуется для сервера)
|
||||||
|
|
||||||
|
- **Цена:** pay-per-use, ~$3-15 за 1M токенов (зависит от модели)
|
||||||
|
- **Типичный расход:** одна задача "задеплой сервис" ≈ $0.05-0.30
|
||||||
|
- **Что даёт:** полный контроль, нет лимитов по частоте (только по деньгам)
|
||||||
|
- **Подходит для:** автоматического агента, частых задач
|
||||||
|
|
||||||
|
**Как получить:**
|
||||||
|
1. Зайти на [console.anthropic.com](https://console.anthropic.com)
|
||||||
|
2. Settings → API Keys → Create Key
|
||||||
|
3. Пополнить баланс через Settings → Billing (минимум $5)
|
||||||
|
|
||||||
|
**Рекомендуемая модель:** `claude-sonnet-4-6` — баланс цены и качества для инфра-задач.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Установка Claude Code на VPS-2
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Установить Node.js 20+
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||||
|
sudo apt-get install -y nodejs
|
||||||
|
|
||||||
|
# Установить Claude Code
|
||||||
|
sudo npm install -g @anthropic-ai/claude-code
|
||||||
|
|
||||||
|
# Проверить
|
||||||
|
claude --version
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Конфигурация для инфра-агента
|
||||||
|
|
||||||
|
Создать `/opt/claude-agent/` с нужными ключами и репозиторием:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /opt/claude-agent
|
||||||
|
cd /opt/claude-agent
|
||||||
|
git clone git@git.csrx.ru:jack/infra.git repo
|
||||||
|
```
|
||||||
|
|
||||||
|
Файл `/opt/claude-agent/.env`:
|
||||||
|
```bash
|
||||||
|
ANTHROPIC_API_KEY=sk-ant-...
|
||||||
|
VAULT_PASSWORD=xXx9uZa_L1Zn!
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрипт запуска `/opt/claude-agent/run-task.sh`:
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TASK="${1:-}"
|
||||||
|
if [ -z "$TASK" ]; then
|
||||||
|
echo "Usage: $0 'task description'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source /opt/claude-agent/.env
|
||||||
|
export ANTHROPIC_API_KEY
|
||||||
|
|
||||||
|
cd /opt/claude-agent/repo
|
||||||
|
git pull origin master
|
||||||
|
|
||||||
|
echo "$VAULT_PASSWORD" > ~/.vault-password-file
|
||||||
|
chmod 600 ~/.vault-password-file
|
||||||
|
|
||||||
|
claude --print "$TASK" \
|
||||||
|
--allowedTools "Bash,Read,Edit,Write,Glob,Grep" \
|
||||||
|
--model claude-sonnet-4-6 \
|
||||||
|
2>&1 | tee /opt/claude-agent/logs/$(date +%Y%m%d-%H%M%S).log
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Простой Telegram-бот для управления агентом
|
||||||
|
|
||||||
|
Самый удобный интерфейс — бот в Telegram. Ты пишешь задачу, бот запускает Claude, присылает результат.
|
||||||
|
|
||||||
|
**Стек:** Python + python-telegram-bot + subprocess
|
||||||
|
|
||||||
|
```python
|
||||||
|
# /opt/claude-agent/bot.py
|
||||||
|
import subprocess, logging
|
||||||
|
from telegram import Update
|
||||||
|
from telegram.ext import Application, MessageHandler, filters, ContextTypes
|
||||||
|
|
||||||
|
ALLOWED_USER_ID = 123456789 # твой Telegram ID
|
||||||
|
|
||||||
|
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
if update.effective_user.id != ALLOWED_USER_ID:
|
||||||
|
return
|
||||||
|
|
||||||
|
task = update.message.text
|
||||||
|
await update.message.reply_text(f"🤖 Запускаю задачу:\n{task}")
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
["/opt/claude-agent/run-task.sh", task],
|
||||||
|
capture_output=True, text=True, timeout=600
|
||||||
|
)
|
||||||
|
|
||||||
|
output = result.stdout[-4000:] if len(result.stdout) > 4000 else result.stdout
|
||||||
|
await update.message.reply_text(f"✅ Готово:\n```{output}```", parse_mode="Markdown")
|
||||||
|
|
||||||
|
app = Application.builder().token("BOT_TOKEN").build()
|
||||||
|
app.add_handler(MessageHandler(filters.TEXT, handle_message))
|
||||||
|
app.run_polling()
|
||||||
|
```
|
||||||
|
|
||||||
|
Запуск как systemd сервис:
|
||||||
|
```ini
|
||||||
|
# /etc/systemd/system/claude-agent-bot.service
|
||||||
|
[Unit]
|
||||||
|
Description=Claude Code Infrastructure Agent Bot
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=/opt/claude-agent
|
||||||
|
ExecStart=/usr/bin/python3 bot.py
|
||||||
|
Restart=always
|
||||||
|
EnvironmentFile=/opt/claude-agent/.env
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Права и безопасность
|
||||||
|
|
||||||
|
Агент имеет доступ к:
|
||||||
|
- Репозиторию инфры (git clone)
|
||||||
|
- SSH-ключу для деплоя на серверы
|
||||||
|
- Vault-паролю
|
||||||
|
|
||||||
|
**Минимально необходимые права:**
|
||||||
|
- SSH-ключ с правами `deploy` пользователя (не root)
|
||||||
|
- Ansible vault password
|
||||||
|
- Git push права в репозиторий
|
||||||
|
|
||||||
|
**Что НЕ давать агенту:**
|
||||||
|
- Root SSH-доступ
|
||||||
|
- Доступ к продакшен БД напрямую
|
||||||
|
- Billing API ключи облачного провайдера
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Стоимость использования
|
||||||
|
|
||||||
|
Типичные задачи и примерная стоимость (claude-sonnet-4-6):
|
||||||
|
|
||||||
|
| Задача | Токены (≈) | Стоимость |
|
||||||
|
|--------|-----------|-----------|
|
||||||
|
| Проверить статус сервисов | 5K | $0.02 |
|
||||||
|
| Обновить один сервис | 20K | $0.06 |
|
||||||
|
| Добавить новый сервис в инфру | 50K | $0.15 |
|
||||||
|
| Полный деплой с отладкой | 100-200K | $0.30-0.60 |
|
||||||
|
|
||||||
|
При 10-20 задачах в месяц: **$2-10/мес** на API.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Итого: что покупать
|
||||||
|
|
||||||
|
1. **Anthropic API Key** — [console.anthropic.com](https://console.anthropic.com), пополнить на $20 (хватит на несколько месяцев)
|
||||||
|
2. **VPS-2** на Timeweb Cloud — 2 ГБ RAM, 2 vCPU (~400 руб/мес)
|
||||||
|
3. **Telegram Bot Token** — через @BotFather в Telegram (бесплатно)
|
||||||
|
|
||||||
|
Итого: ~$20 единоразово + ~$5-10/мес на использование.
|
||||||
127
docs/infrastructure-plan.md
Normal file
127
docs/infrastructure-plan.md
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
# Infrastructure Plan
|
||||||
|
|
||||||
|
## Текущее состояние сервера (март 2026)
|
||||||
|
|
||||||
|
### Сервер: 87.249.49.32 (VPS-1, основной)
|
||||||
|
|
||||||
|
| Ресурс | Состояние | Оценка |
|
||||||
|
|--------|-----------|--------|
|
||||||
|
| CPU | 1 vCPU, load avg 1.63 | 🔴 Критично |
|
||||||
|
| RAM | 1.9 ГБ, свободно 99 МБ | 🔴 Критично |
|
||||||
|
| Swap | Отсутствует | 🔴 Опасно |
|
||||||
|
| Disk | 29 ГБ, 45% занято | 🟢 Норм |
|
||||||
|
|
||||||
|
**Вывод:** сервер работает на пределе. Любой пик нагрузки (деплой через CI/CD, обращение к Plane, тяжёлый запрос) приводит к конкуренции за RAM без возможности свопирования — процессы убиваются OOM killer'ом.
|
||||||
|
|
||||||
|
### Крупнейшие потребители RAM
|
||||||
|
|
||||||
|
| Контейнер | RAM |
|
||||||
|
|-----------|-----|
|
||||||
|
| plane-minio | 244 МБ |
|
||||||
|
| plane-api | 198 МБ |
|
||||||
|
| plane-worker | 178 МБ |
|
||||||
|
| plane-beat | 150 МБ |
|
||||||
|
| plane-space | 111 МБ |
|
||||||
|
| forgejo | 140 МБ |
|
||||||
|
| plane-db | 40 МБ |
|
||||||
|
| forgejo-db | 41 МБ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Немедленные действия (без смены тарифа)
|
||||||
|
|
||||||
|
### 1. Добавить swap (делается за 2 минуты)
|
||||||
|
```bash
|
||||||
|
sudo fallocate -l 2G /swapfile
|
||||||
|
sudo chmod 600 /swapfile
|
||||||
|
sudo mkswap /swapfile
|
||||||
|
sudo swapon /swapfile
|
||||||
|
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
||||||
|
```
|
||||||
|
Это не решит проблему, но защитит от внезапных OOM kills.
|
||||||
|
|
||||||
|
### 2. Ограничить mem_limit у Plane-сервисов
|
||||||
|
- `plane-worker` и `plane-beat` сейчас без лимита, жрут ~150-180 МБ каждый
|
||||||
|
- Поставить `mem_limit: 256m` на каждый
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Архитектура: два сервера
|
||||||
|
|
||||||
|
### Рекомендуемая схема
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
Internet ──────────────── │ VPS-1 (основной, 87.249.49.32) │
|
||||||
|
│ │
|
||||||
|
│ Traefik (80/443) │
|
||||||
|
│ ├── Forgejo (git.csrx.ru) │
|
||||||
|
│ ├── Vaultwarden (vault.) │
|
||||||
|
│ ├── Plane (plane.) │
|
||||||
|
│ ├── Syncthing (sync.) │
|
||||||
|
│ └── Forgejo Runner │
|
||||||
|
└─────────────────────────────────┘
|
||||||
|
│
|
||||||
|
Ansible SSH
|
||||||
|
│
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ VPS-2 (мониторинг + тулзы) │
|
||||||
|
│ │
|
||||||
|
│ Traefik (80/443) │
|
||||||
|
│ ├── Grafana (dashboard.) │
|
||||||
|
│ ├── Prometheus (internal) │
|
||||||
|
│ ├── cAdvisor (internal) │
|
||||||
|
│ ├── Node Exporter × 2 servers │
|
||||||
|
│ └── Claude Code Agent │
|
||||||
|
└─────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Почему два сервера?
|
||||||
|
|
||||||
|
1. **Изоляция:** мониторинг не ест ресурсы продакшен-сервисов
|
||||||
|
2. **Мониторинг мониторит продакшен снаружи** — видит проблемы даже при перегрузке VPS-1
|
||||||
|
3. **Claude Agent** работает на отдельной машине — не мешает пользователям
|
||||||
|
4. **Цена:** маленький VPS для мониторинга стоит 200-400 руб/мес
|
||||||
|
|
||||||
|
### Параметры VPS-2 (мониторинг)
|
||||||
|
|
||||||
|
Минимум: **2 vCPU, 2 ГБ RAM, 20 ГБ SSD** — этого хватит для Grafana+Prometheus+Claude Agent.
|
||||||
|
|
||||||
|
### Параметры для апгрейда VPS-1 (опционально)
|
||||||
|
|
||||||
|
Текущий тариф явно перегружен. Рекомендую апгрейд до **2 vCPU, 4 ГБ RAM** — это закроет проблему RAM и CPU.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Провайдеры
|
||||||
|
|
||||||
|
Текущий сервер на **Timeweb Cloud** (судя по IP-диапазону и ключу `timeweb` в ~/.ssh/).
|
||||||
|
|
||||||
|
**Варианты для VPS-2:**
|
||||||
|
- **Timeweb Cloud** — тот же провайдер, можно управлять из одного кабинета, хороший пинг между серверами (оба в одном датацентре)
|
||||||
|
- **Hetzner** — дешевле, но выше пинг из России
|
||||||
|
- **Selectel / Beeline Cloud** — российские, быстро
|
||||||
|
|
||||||
|
**Рекомендация:** VPS-2 тоже на Timeweb Cloud — серверы в одной сети, внутренний трафик между ними бесплатный или очень дешёвый.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что деплоить на VPS-2 через Ansible
|
||||||
|
|
||||||
|
Добавить VPS-2 в `inventory/hosts.ini` как отдельный хост `monitoring`. Создать роль `monitoring` с:
|
||||||
|
|
||||||
|
- Prometheus + Node Exporter (scrape обоих серверов)
|
||||||
|
- Grafana с дашбордами
|
||||||
|
- cAdvisor (мониторит контейнеры VPS-2)
|
||||||
|
- Remote scrape Node Exporter на VPS-1 (добавить Node Exporter на VPS-1 без публичного доступа, через Prometheus federation или прямой scrape по внутреннему IP)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Таймлайн
|
||||||
|
|
||||||
|
| Приоритет | Действие | Время |
|
||||||
|
|-----------|----------|-------|
|
||||||
|
| 🔴 Сейчас | Добавить swap на VPS-1 | 5 мин |
|
||||||
|
| 🟡 Эта неделя | Купить VPS-2, задеплоить мониторинг | 1-2 ч |
|
||||||
|
| 🟡 Эта неделя | Апгрейд VPS-1 до 4 ГБ RAM | 10 мин (перезагрузка) |
|
||||||
|
| 🟢 Позже | Claude Agent на VPS-2 | см. claude-agent.md |
|
||||||
Loading…
Reference in a new issue