Files
md2vk/docs/deploy.md
T

127 lines
5.0 KiB
Markdown

# md2vk — Деплой
## Топология
```
https://md2vk.nixg.ru (Caddy на vps02, basic auth)
└─ reverse_proxy 10.8.0.2:8420 (WireGuard: vps02 .4 → bigbox .1)
└─ docker-контейнер md2vk на bigbox, 127.0.0.1:8420
```
- Порт приложения **8420** (8000 занят docker-search-api на bigbox).
- Контейнер слушает на 127.0.0.1:8420 (снаружи bigbox не открыт).
## bigbox (10.8.0.2) — приложение
```bash
cd /opt/md2vk
make docker-up # docker compose up -d --build
docker ps | grep md2vk # статус
curl -s http://127.0.0.1:8420/api/v1/health # {"status":"ok"}
```
- Данные: named volume `md2vk_data` → `/data/md2vk.db` (SQLite).
- Секрет: `./secrets/token_encryption_key` → `/run/secrets/token_encryption_key`.
- Логи аудита: `./logs/` монтируется в `/logs`.
- Health: `/api/v1/health`, проверяется Docker healthcheck.
- Восстановление после перезагрузки: `restart: unless-stopped`.
- Если надо пересоздать БД — удалить том (только по явной команде, данные!):
`docker compose down -v && make docker-up` (НЕ делать без подтверждения).
## Создание пользователя и API-ключа
```bash
cd /opt/md2vk
source venv/bin/activate
TOKEN_ENCRYPTION_KEY_FILE=/opt/md2vk/secrets/token_encryption_key ./scripts/create_user.py \
--name estorozhenko --api-key-out secrets/estorozhenko_api_key.txt
# вывод: API key сохранён в secrets/estorozhenko_api_key.txt (md2vk_...)
```
Источник: `scripts/create_user.py` (добавляет User с сгенерированным ключом; ключ отображается один раз).
## vps02 (87.242.100.206) — Caddy
Файл `/opt/caddy/Caddyfile` на vps02, секция:
```
md2vk.nixg.ru {
basic_auth /* {
estorozhenko $2a$14$T5gAji7gmg1t3Ifxw0CJy.jat9vpFfOiJIE8j5bnHynEVH1q.QTPS
}
reverse_proxy 10.8.0.2:8420
}
```
Применить (контейнер caddy, монтирует Caddyfile):
```bash
ssh vps02
docker exec caddy caddy validate --config /etc/caddy/Caddyfile # проверить синтаксис
docker exec caddy caddy reload --config /etc/caddy/Caddyfile # перезагрузить
# если нужно: docker restart caddy
```
- TLS: Caddy автоматически выпускает Let's Encrypt сертификат для md2vk.nixg.ru (acme в Caddyfile: `email kpa39l@yandex.ru`).
- Сертификат на caddy_data (volume), переживает рестарты.
## vps02 — fail2ban (блокировка после 5 попыток)
Пакет ставится на vps02 (Debian/Ubuntu):
```bash
ssh vps02
sudo apt-get update && sudo apt-get install -y fail2ban
```
Конфиг jail (`/etc/fail2ban/jail.local`) и фильтр (`/etc/fail2ban/filter.d/md2vk.conf`):
```ini
# /etc/fail2ban/filter.d/md2vk.conf
[Definition]
failregex = ^.*"status":401.*
ignoreregex =
```
```ini
# /etc/fail2ban/jail.local
[md2vk]
enabled = true
port = http,https
filter = md2vk
logpath = /var/log/caddy/access.log
maxretry = 5
findtime = 600
bantime = -1
action = iptables-allports
```
- Лог Caddy в JSON: настроить в Caddyfile `log { output file /var/log/caddy/access.log format json }` (глобальный блок).
- Перезапуск: `sudo systemctl restart fail2ban`.
- Проверка: `sudo fail2ban-client status md2vk`.
- Ручной unban: `sudo fail2ban-client -c /etc/fail2ban unban <ip>`.
## Сквозная проверка
```bash
# 1. health через Caddy (без auth → 401)
curl -s -o /dev/null -w "%{http_code}\n" https://md2vk.nixg.ru/api/v1/health # 401
# 2. health c auth → 200
curl -s -u 'estorozhenko:<пароль>' https://md2vk.nixg.ru/api/v1/health # {"status":"ok"}
# 3. публикация не требует VK-токена? нет — конвертация:
curl -s -u 'estorozhenko:<пароль>' -H 'Authorization: Bearer <api_key>' \
-X POST https://md2vk.nixg.ru/api/v1/convert \
-H 'Content-Type: application/json' \
-d '{"message_md":"**test** *curl*"}' # format_data
# 4. баним проверкой: 5 раз неверный пароль → fail2ban ban IP
for i in 1 2 3 4 5 6; do curl -s -o /dev/null -w "%{http_code}\n" -u 'estorozhenko:wrong' https://md2vk.nixg.ru/api/v1/health; done
# → 401 ×6, затем соединение DROP (curl timeout)
sudo fail2ban-client status md2vk # IP в banned
sudo fail2ban-client unban <ваш-ip>
```
## Восстановление после аварии
- Приложение: `docker compose up -d --force-recreate` на bigbox.
- Caddy: `docker restart caddy` на vps02 (volume caddy_data хранит сертификаты).
- БД: том `md2vk_data`; бэкап = копия `/opt/md2vk/data/md2vk.db` (вне контейнера) — включена в homelab-backup (/opt/backup).