---
name: contabo-project-map
description: >
  Complete map of all projects on Contabo VPS, including
  locations, ports, services, deployment procedures, and protection plan.
  Load this skill at session start to understand the full landscape.
category: devops
sensitive: false
---

# 🗺️ Contabo Project Map — Hermes Master Reference

## Server Specs
- **Host**: Contabo VPS (Ubuntu 24.04, systemd)
- **Disk**: 72G total (~38G used, ~34G free)  
- **RAM**: 7.8Gi (5.4Gi used, 2.3Gi available)
- **Docker**: docker-ce + containerd
- **SSL**: Certbot (Let's Encrypt) — `/etc/letsencrypt/live/sailor.bar/`
- **Security**: UFW enabled, fail2ban (SSH brute force), SSH key-only access
- **Uptime**: 8+ days (по состоянию на 16.05.2026)

---

## 1️⃣ Sailor.bar Platform 🚢

### Static Site (React/Vite SPA)
- **Served from**: `/var/www/sailor.bar/`
- **Source repo**: `/opt/sailor-bar-source/` (git → GitHub)
- **nginx**: Serves `/` from this directory
- **Deploy**: `/opt/deploy-sailor-bar.sh` (git pull → cp → reload nginx)

### API + Telegram Bot (SailorBarBot) ⚠️ КРИТИЧЕСКИ ВАЖНО
- **Path**: `/opt/sailor-bar/artifacts/api-server/` → `dist/index.mjs`
- **Runs as**: `sailor-bar-bot.service` (systemd, enabled, auto-restart)
- **Port**: `3001` — nginx proxies `/api/` → `127.0.0.1:3001`
- **Bot**: @SailorBarBot — webhook через `/api/bot/webhook`
- **DB**: PostgreSQL на **порту 5433** (НЕ 5432!), БД `sailor_bar`, юзер `sea_connect`
- **Restart**: `systemctl restart sailor-bar-bot.service`
- **Health**: `curl http://localhost:3001/api/healthz` → `{"status":"ok"}`
- **Deploy**: `cd /opt/sailor-bar-source && npm run build:api && systemctl restart sailor-bar-bot.service`

> ⚠️ **ЧЕГО НЕ ТРОГАТЬ**: Postgres порт 5433 (не путать с 5432 от goclaw!), `.env` файлы в `/opt/sailor-bar/` и `/opt/sailor-bar/artifacts/api-server/`, nginx location `/api/`, исходники `/opt/sailor-bar-source/`.

### nginx config
- `/` → `/var/www/sailor.bar/` (static files)
- `/api/` → proxy to `127.0.0.1:3001` (SeaConnect API + webhook)
- `/bot` → proxy to `127.0.0.1:3000` (sailorbar-bot)
- `/assets/` → `/var/www/sailor.bar/assets/`
- `/images/` → `/var/www/sailor.bar/images/`

---

## 2️⃣ Valentinnews Digest 📰

### Active Pipeline
- **Orchastrator**: `python3 /opt/data/scripts/deploy_news_digest.py`
- **Cron**: Daily at `06:00 UTC` (cronjob `2dae8e718baf`)
- **Output**: https://valentinnews.sailor.bar
- **Local repo**: `/opt/hermes/valentinnews.sailor.bar/` (git → GitHub Pages)
- **Remote**: `github.com/valldun1/valentinnews.sailor.bar`

| Script | Purpose |
|---|---|
| `fetch_all_news.py` | 7 categories + currencies (USD/EUR/CNY/GBP) + Brent oil + Google stock |
| `ai_summarize.py` | AI summarization via NVIDIA NIM (free Llama 3.3 70B) |
| `generate_digest_html.py` | Dark-theme HTML with currency/market bar |
| `deploy_news_digest.py` | Full orchestrator |
| `config.yaml` + `.env` | API keys for NVIDIA/OpenRouter |

### 7 Categories
kremlin 🔵, china 🟡, belarus 🟢, west 🔴, ai_tech 🤖, space 🚀, world 🌍

### 11 Habr hubs in ai_tech
AI, Programming, Security, DevOps, GameDev, Popular Science, Data Engineering, Nginx, Career + arXiv cs.AI, cs.RO, TechCrunch

### Market data sources
- Currencies: cbr-xml-daily.ru (ЦБ РФ)
- Oil/Stock: Yahoo Finance (BZ=F, GOOGL)

### Legacy (NOT active)
`custom-news-site` skill — simpler pipeline without markets/currencies. Fallback only.

---

## 3️⃣ Docker Containers 🐳

| Name | Image | Port | Purpose |
|---|---|---|---|---|
| hermes | hermes-agent:latest | — | Agent, data at `/opt/hermes-data/` |
| n8n-old | n8nio/n8n | 5678 | Workflow automation (переименован в n8n-old) |
| portainer | portainer/portainer-ce | 9000 | Docker management |
| goclaw-goclaw-1 | ghcr.io/nextlevelbuilder/goclaw | 18790 | GoClaw — хостинг агентов (Лисёнок 🦊) |
| goclaw-postgres-1 | pgvector/pgvector:pg18 | 5432 | PostgreSQL с pgvector для GoClaw |
| goclaw-chrome-1 | zenika/alpine-chrome:124 | 9222 | Remote browser для агентов GoClaw |

### Access
- Portainer: port 9000, admin login
- n8n: port 5678, login via Google

---

## 4️⃣ Systemd Services 🎛️

| Сервис | Статус | Порт | Описание |
|---|---|---|---|
| `sailor-bar-bot.service` | ✅ active | 3001 | **SailorBarBot** — основной бот (Postgres 5433) |
| `sailorbar-bot.service` | ✅ active | 3000 | Старый бот (legacy, вернулся в строй) |
| `hermes.service` | ✅ active | — | Hermes Agent (системный, отдельно от Docker) |
| `nginx.service` | ✅ active | 80/443 | Веб-сервер |

> **⚠️ Hermes в двух экземплярах**: Docker-контейнер `hermes` + systemd `hermes.service`. Не конфликтуют — разное окружение.

## 5️⃣ Webhook Deploy 🚀

- **Скрипт**: `python3 /opt/webhook-deploy.py` на порту **9002**
- **Эндпоинт**: POST `/deploy/<SECRET>` → запускает `/opt/deploy-sailor-bar.sh`
- **Секрет**: хранится в коде скрипта

## 5️⃣ Webhook Deploy 🚀

- **Скрипт**: `python3 /opt/webhook-deploy.py` на порту **9002**
- **Эндпоинт**: POST `/deploy/<SECRET>` → запускает `/opt/deploy-sailor-bar.sh`
- **Секрет**: хранится в коде скрипта

## 6️⃣ Новые системные структуры 🆕

- **`/opt/ai/`** — новая директория:
  - `goclaw/` — компоуз и конфиги (legacy, не используется)
  - `hermes/` — конфиги Hermes
  - `hermes-agent/` — бинарник Hermes (для systemd-сервиса)
- **PostgreSQL на хосте**: порт 5433 (для sailor_bar), отдельно от Docker pgvector (5432)

## 7️⃣ Мониторинг 🛡️

- **Скрипт**: `/usr/local/bin/health-monitor.sh`
- **Расписание**: каждые 15 минут (cron `*/15 * * * *`)
- **Проверяет**: все systemd-сервисы, порты (3001, 9000, 5678), Docker, HTTPS, API `/api/bot/webhook`, диск <85%, load average
- **Алерты**: Telegram — бот Hermes сервера → @Valkonstantinov (chat_id: 5838842946)
- **Лог**: `/var/log/health-monitor.log`

## 7️⃣ Резервное копирование 💾

- **PostgreSQL (goclaw)**: pg_dump через Docker, ежедневно в 05:00, ротация 10 копий
- **Скрипт**: `/var/backups/postgres/backup-goclaw.sh`
- **Лог**: `/var/backups/postgres/backup.log`

---

## 8️⃣ GoClaw / Лисёнок 🦊

- **Container**: `goclaw-goclaw-1` — порт `18790`
- **Postgres**: `goclaw-postgres-1` — порт **5432** (pgvector/pgvector:pg18)
- **Chrome**: `goclaw-chrome-1` — порт 9222 (remote browser для агента)
- **Архитектура**: SPA (React) + WebSocket (`connect-src self ws:`)
- **API**: Только `/health` → `{"status":"ok","protocol":3}`, остальное SPA с клиентским роутингом
- **Агенты**: внутри GoClaw, идентифицируются по токенам вида `goclaw_<hash>`
- **Лисёнок**: новый агент с графовой памятью (через pgvector)
- **Коммуникация**: только через WebSocket внутри GoClaw. Внешнее взаимодействие — через Кэпа (Telegram) или общий git в `/opt/data/agents/`

### Подключение к pgvector GoClaw
```bash
# Хост напрямую (из другого контейнера в host-сети)
psql -h 157.173.122.51 -p 5432 -U goclaw -d goclaw
# Через Docker (например из Hermes контейнера, если в одной сети с хостом)
docker exec -it goclaw-postgres-1 psql -U goclaw -d goclaw
```

---

## 9️⃣ Protection Plan 🛡️

### Current Security ✅
- SSH key-only, UFW enabled, fail2ban active
- Docker containers non-root (Hermes restricted: read-only FS)
- certbot auto-renewal

### Backup Strategy
| What | How | Frequency |
|---|---|---|
| Code repos | Git push to GitHub | Each deploy |
| n8n workflows | Export JSON | As needed |
| Server config | nginx, ufw rules | Save as notes |
| **PostgreSQL (goclaw — legacy)** | pg_dump через Docker (скрипт ещё бежит) | Ежедневно 05:00, ротация 10 копий |

### Weaknesses 🔴
1. **No full backup** — no VPS snapshot/image (⚠️ only remaining risk)
2. **Два Hermes** — Docker + systemd. Потенциально не конфликтуют, но нужно мониторить.

### Fixed ✅
- ✅ **PostgreSQL backup** — daily pg_dump cron at `05:00`, 10-backup rotation
- ✅ **Systemd service** — `sailor-bar-bot.service` (enabled, always restarts on crash)
- ✅ **Health monitoring** — every 15 min, алерты в Telegram @Valkonstantinov (chat_id 5838842946)
- ✅ **Webhook deploy** — port 9002, `/deploy/<SECRET>` → авто-деплой Sailor.bar
- ✅ **Vision** — OpenRouter + google/gemini-2.5-flash (дешёвая модель)
- ✅ **GoClaw** — активен, порт 18790, агент Лисёнок 🦊

### Quick Recovery
1. Redeploy Docker containers from images
2. Clone GitHub repos (Sailor-bar, valentinnews)
3. Reinstall nginx + certbot + UFW rules
4. Restore PostgreSQL from saved dump
5. Re-register Telegram webhook for SeaConnect
