# VPS Hosting — Руководство для ИИ-агентов

> **Для кого:** Claude Code, Hermes, Crush, Qwen и др. агенты, работающие с VPS `31.58.134.118`.
> **Канон:** этот файл + [VPS_HOSTING.md](VPS_HOSTING.md) + [SECURITY.md](SECURITY.md).
> **Золотое правило:** любые изменения на VPS — через `ssh vps-proxy`, всегда проверять сервис после.

---

## 🔑 Доступ

```bash
ssh vps-proxy   # root@31.58.134.118, ключ ~/.ssh/id_ed25519_vps_6627 (беспарольный)
```
- Парольная авторизация SSH **отключена** (hardening). `sshpass` НЕ работает.
- Secrets (root-pass исторический, SOCKS5-pass): `/home/samurai/.secrets_dir/vps-proxy-31.58.134.118.env` (chmod 600).

---

## 🌐 Текущее состояние сервисов

| URL (публичный) | Backend | Контейнер/путь |
|-----------------|---------|----------------|
| `https://31.58.134.118.nip.io/` | статика | `/var/www/samurai-ai/` |
| `https://goida.31.58.134.118.nip.io` | Flask/waitress | Docker `goida-vpn-site` → `127.0.0.1:5001` |

SSL: Let's Encrypt (auto), Caddy управляет.

---

## 📦 Публикация нового сайта (стандартная процедура)

### Вариант A — статичный сайт
```bash
# 1. Упаковать (на llmserver)
tar --exclude='{__pycache__,.git,node_modules,.venv,*.pyc}' -czf /tmp/site.tar.gz -C proj/ .

# 2. Передать + разместить
scp /tmp/site.tar.gz vps-proxy:/tmp/
ssh vps-proxy 'mkdir -p /var/www/<name> && tar xzf /tmp/site.tar.gz -C /var/www/<name> && rm /tmp/site.tar.gz'

# 3. Добавить в Caddyfile (блок домена или handle_path для подпути)
# 4. caddy fmt --overwrite /etc/caddy/Caddyfile && systemctl reload caddy
```

### Вариант B — Docker-сервис (Flask/Node/Python)
```bash
# 1. Упаковать проект
# 2. scp на VPS → /opt/stack/<name>/
# 3. Создать Dockerfile + docker-compose.yml (БЕЗ публикации порта наружу — только 127.0.0.1:PORT)
#    ports: ["127.0.0.1:PORT:container_port"]
# 4. cd /opt/stack/<name> && docker compose up -d --build
# 5. В Caddyfile:
#       handle_path /<path>* { reverse_proxy 127.0.0.1:PORT }
# 6. caddy fmt --overwrite && systemctl reload caddy
# 7. curl -s -o /dev/null -w '%{http_code}' https://31.58.134.118.nip.io/<path>
```

### Подключение домена (после регистрации владельцем)
1. Владелец регистрирует домен + A-record → `31.58.134.118`
2. Добавить в Caddyfile:
   ```
   example.com {
       root * /var/www/<name>
       file_server
       # или reverse_proxy 127.0.0.1:PORT
   }
   ```
3. `caddy fmt --overwrite && systemctl reload caddy`
4. Caddy **сам** выпустит SSL (Let's Encrypt) — ждать ~30 сек.

---

## ⚠️ Безопасность — НЕ НАРУШАТЬ

1. **НЕ включать** `PasswordAuthentication yes` в sshd_config.
2. **НЕ открывать** новые порты в UFW без необходимости. Закрытые: SOCKS5 :1080 (OmniRoute-off), admin :2019 (localhost).
3. **НЕ публиковать** Docker-порты на `0.0.0.0` — только `127.0.0.1:PORT` + reverse-proxy через Caddy.
4. **НЕ перезаписывать** `/etc/caddy/Caddyfile` без `caddy fmt --overwrite` + `systemctl reload caddy` (иначе синтаксис-ошибка рвёт весь веб).
5. **НЕ трогать** Amnezia VPN контейнеры (порты 51820/51821/46673) — активные пользователи.
6. Пароли/секреты — **только** в `/home/samurai/.secrets_dir/` (chmod 600), никогда в plaintext в каноне/memory.
7. После любых изменений — `systemctl status <svc>` + внешний curl-тест.

---

## 🛠️ Частые операции

```bash
# Статус всего
ssh vps-proxy 'systemctl is-active caddy docker fail2ban unattended-upgrades; docker ps --format "{{.Names}}: {{.Status}}"'

# Логи Caddy (SSL-ошибки, proxy-проблемы)
ssh vps-proxy 'journalctl -u caddy -n 30 --no-pager'

# Перезапуск сайта
ssh vps-proxy 'cd /opt/stack/<name> && docker compose restart'

# fail2ban: кто забанен
ssh vps-proxy 'fail2ban-client status sshd'

# Внешний тест
curl -s -o /dev/null -w '%{http_code}\n' https://31.58.134.118.nip.io/
```

---

## 🔄 Откат/восстановление

| Что | Где бэкап |
|-----|-----------|
| sshd_config | `/etc/ssh/sshd_config.bak-hardening` (на VPS) |
| OmniRoute storage (proxy) | `~/.omniroute/storage.sqlite.bak-proxy-*` (на llmserver) |
| Caddy autosave | `/var/lib/caddy/.config/caddy/` (на VPS) |

**Если сломался веб:** `ssh vps-proxy 'systemctl restart caddy'` → проверь `journalctl -u caddy`.
**Если потерялся SSH-доступ:** использовать пароль через панель хостинга (CGI GLOBAL) — последний резерв.

---

## 🧠 Memory (для долгосрочной памяти агентов)

- `vps_hosting_node_20260626.md` — сводка узла
- `proxy_off_password_harden_20260626.md` — SOCKS5 ротация
- `subagent_combo_antigravity_fix_20260626.md` — связанный контекст

---

*Канон обновлён 2026-06-27. При противоречии — этот файл + VPS_HOSTING.md приоритет над старыми memory-записями.*
