Expand README with PostgreSQL documentation and updated setup guide

This commit is contained in:
tgvpn
2026-05-21 01:16:28 +03:00
parent 5e3229e998
commit fd22714c9b
+207 -14
View File
@@ -2,7 +2,18 @@
**Версия:** [0.20.0](CHANGELOG.md)
Telegram-бот на Go (базовое приветствие; далее — VPN-функции).
Telegram-бот на Go для управления VPN через панель [Remnawave](https://docs.rw/): проверка панели, создание пользователей, назначение сквадов. Данные хранятся в **PostgreSQL**.
## Содержание
- [Требования](#требования)
- [Быстрый старт](#быстрый-старт-docker-compose)
- [PostgreSQL](#postgresql)
- [Развёртывание на VPS](#развёртывание-на-vps-linux)
- [Обновление бота](#обновление-бота)
- [Переменные окружения](#переменные-окружения)
- [Админ-меню](#админ-меню-в-боте)
- [Устранение неполадок](#устранение-неполадок)
## Требования
@@ -43,12 +54,16 @@ REMNAWAVE_PANEL_NAME=Панель 1
REMNAWAVE_PANEL_URL=https://panel.example.com
REMNAWAVE_API_TOKEN=токен_из_панели
REMNAWAVE_SUBSCRIPTION_URL=https://sub.example.com
DATABASE_URL=postgres://tgvpn:tgvpn@db:5432/tgvpn?sslmode=disable
DEFAULT_USER_DAYS=30
```
> **Важно:** файл `.env` не попадает в git и не копируется в образ. Compose передаёт переменные в контейнер при старте.
### 3. Сборка и запуск
Поднимаются два сервиса: **PostgreSQL** (`db`) и **бот** (`bot`). Бот стартует только после готовности БД.
```bash
docker compose up -d --build
```
@@ -56,23 +71,164 @@ docker compose up -d --build
### 4. Проверка
```bash
# логи (должно быть: «бот @имя_бота запущен»)
docker compose logs -f bot
# статус контейнера
# статус (db — healthy, bot — running)
docker compose ps
# логи бота (должно быть: «postgres ok», «бот @имя запущен»)
docker compose logs --tail=30 bot
# логи PostgreSQL
docker compose logs --tail=20 db
```
В Telegram откройте бота и отправьте `/start`.
В Telegram: `/start`, от админа — `/admin squads`, `/admin user`.
### 5. Остановка
```bash
# остановить контейнеры (данные БД сохраняются в volume pgdata)
docker compose down
# удалить и данные БД (осторожно!)
docker compose down -v
```
---
## PostgreSQL
Бот **не работает без PostgreSQL**: при старте проверяется `DATABASE_URL`, применяется миграция, далее идёт работа с БД.
### Роль базы данных
| Таблица | Назначение |
|---------|------------|
| `telegram_users` | Пользователи Telegram, зашедшие в бота (`/start`) |
| `vpn_users` | Созданные в Remnawave аккаунты: UUID, логин, сквады, срок |
| `admin_wizard` | Состояние мастера админа (создание пользователя, назначение сквадов) |
Миграции лежат в `internal/db/migrations/` и применяются **автоматически** при каждом запуске бота (`CREATE TABLE IF NOT EXISTS`).
### Схема в Docker Compose
```yaml
services:
db: # PostgreSQL 16, volume pgdata
bot: # ждёт healthy у db, затем стартует
```
Параметры по умолчанию (см. `docker-compose.yml`):
| Параметр | Значение |
|----------|----------|
| Хост (внутри compose) | `db` |
| Порт | `5432` |
| База | `tgvpn` |
| Пользователь | `tgvpn` |
| Пароль | `tgvpn` |
Строка подключения для бота:
```env
DATABASE_URL=postgres://tgvpn:tgvpn@db:5432/tgvpn?sslmode=disable
```
Формат URL (общий вид):
```
postgres://USER:PASSWORD@HOST:PORT/DATABASE?sslmode=disable
```
### Подключение к БД вручную
Из каталога проекта:
```bash
# интерактивная консоль psql внутри контейнера
docker compose exec db psql -U tgvpn -d tgvpn
```
Полезные запросы:
```sql
-- все VPN-пользователи, созданные через бота
SELECT remnawave_username, remnawave_uuid, expire_at, created_at FROM vpn_users;
-- активные мастера админа
SELECT admin_telegram_id, step, updated_at FROM admin_wizard;
\q
```
### Продакшен: смена пароля БД
1. Задайте сильный пароль в `docker-compose.yml` (секция `db.environment`) **или** вынесите в `.env`:
```yaml
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change_me_strong}
```
2. Обновите `DATABASE_URL` в `.env` бота с тем же паролем.
3. Пересоздайте стек:
```bash
docker compose down
docker compose up -d --build
```
> Если меняете пароль у уже существующего volume `pgdata`, может понадобиться сброс volume или `ALTER USER` внутри старой БД.
### Внешний PostgreSQL (без контейнера `db`)
Если БД на отдельном сервере или managed Postgres:
1. Создайте базу и пользователя с правами `CREATE`, `SELECT`, `INSERT`, `UPDATE`, `DELETE`.
2. В `.env` укажите реальный URL:
```env
DATABASE_URL=postgres://user:password@postgres.example.com:5432/tgvpn?sslmode=require
```
3. В `docker-compose.yml` закомментируйте или удалите сервис `db` и `depends_on` у `bot`.
4. Убедитесь, что с хоста бота есть сетевой доступ к порту `5432`.
### Резервное копирование
```bash
# дамп в файл (дата в имени)
docker compose exec -T db pg_dump -U tgvpn tgvpn > backup_$(date +%Y%m%d).sql
# восстановление (на пустую или новую БД)
cat backup_20260101.sql | docker compose exec -T db psql -U tgvpn -d tgvpn
```
Рекомендуется настроить cron на VPS для ежедневных дампов.
### Проверка после деплоя
```bash
docker compose ps
# tgvpn-db running (healthy)
# tgvpn-bot running
docker compose logs bot | grep -i postgres
# ожидается успешный старт без «ping postgres» / «apply migration» ошибок
```
### Ошибки PostgreSQL
| Симптом | Решение |
|---------|---------|
| `DATABASE_URL не задан` | Добавьте переменную в `.env` |
| `connect postgres` / `ping postgres` | Проверьте, что `db` в состоянии `healthy`: `docker compose ps` |
| Бот стартует раньше БД | В compose уже есть `depends_on: condition: service_healthy` — обновите compose |
| `password authentication failed` | Совпадение пароля в `POSTGRES_PASSWORD` и в `DATABASE_URL` |
| Пустые таблицы после создания user | Смотрите логи бота и ответ Remnawave API; запись в `vpn_users` идёт после успешного `POST /api/users` |
---
## Развёртывание на VPS (Linux)
Ниже — пошаговая установка на чистый сервер (Ubuntu 22.04/24.04, Debian 12). Аналогично на других дистрибутивах с Docker.
@@ -126,7 +282,9 @@ cp .env.example .env
nano .env # или vim / vi
```
Укажите реальный `BOT_TOKEN`. Для продакшена оставьте `BOT_DEBUG=false`.
Укажите реальный `BOT_TOKEN`, `DATABASE_URL` (в compose для VPS обычно оставляют `postgres://tgvpn:...@db:5432/...`), Remnawave и при необходимости UUID сквадов (`DEFAULT_*`).
Для продакшена смените пароль PostgreSQL — см. [PostgreSQL → Продакшен](#продакшен-смена-пароля-бд).
Права на секреты:
@@ -145,6 +303,7 @@ docker compose up -d --build
```bash
docker compose ps
docker compose logs --tail=50 bot
docker compose logs --tail=20 db
```
### Шаг 6. Автозапуск после перезагрузки сервера
@@ -285,9 +444,31 @@ docker compose logs -f bot
## Локальная разработка (без Docker)
Нужен запущенный PostgreSQL 16+ (локально или только контейнер БД):
```bash
# вариант: только БД в Docker, бот на хосте
docker compose up -d db
```
В `.env` для локального бота укажите:
```env
DATABASE_URL=postgres://tgvpn:tgvpn@localhost:5432/tgvpn?sslmode=disable
```
Проброс порта в `docker-compose.yml` (если ещё нет):
```yaml
db:
ports:
- "5432:5432"
```
Запуск:
```bash
cp .env.example .env
# укажите BOT_TOKEN в .env
go run .
```
@@ -369,10 +550,16 @@ docker compose logs -f bot
# последние 100 строк логов
docker compose logs --tail=100 bot
# зайти в контейнер (обычно не нужно)
# зайти в контейнер бота
docker compose exec bot sh
# удалить контейнер (образ останется)
# консоль PostgreSQL
docker compose exec db psql -U tgvpn -d tgvpn
# дамп базы
docker compose exec -T db pg_dump -U tgvpn tgvpn > backup.sql
# удалить контейнеры (данные БД в volume сохранятся)
docker compose down
# удалить контейнер и неиспользуемые образы проекта
@@ -385,8 +572,9 @@ docker compose down --rmi local
- Бот использует **long polling**: входящие запросы на ваш сервер **не нужны**, порты открывать не требуется.
- Нужен только **исходящий** доступ к `https://api.telegram.org`.
- Не коммитьте `.env` в git. Не публикуйте `BOT_TOKEN`.
- Контейнер запускается от непривилегированного пользователя `bot` (UID 10001).
- Не коммитьте `.env` в git. Не публикуйте `BOT_TOKEN` и пароль БД.
- PostgreSQL доступен **только внутри docker-сети** (порт наружу не проброшен по умолчанию).
- Контейнер бота запускается от непривилегированного пользователя `bot` (UID 10001).
Если позже добавите **webhook**, понадобится reverse proxy (nginx/Caddy), TLS и открытый порт 443 — это описывается отдельно при появлении функции.
@@ -432,6 +620,10 @@ docker compose logs --tail=200 bot
Чаще всего — пустой `BOT_TOKEN` или ошибка при старте.
### `DATABASE_URL не задан` / ошибки PostgreSQL
См. раздел [PostgreSQL → Ошибки](#ошибки-postgresql).
### Нет доступа к `docker` без sudo
```bash
@@ -449,10 +641,11 @@ tgvpn/
├── internal/
│ ├── bot/ # Telegram, админ-меню, создание пользователей
│ ├── config/ # переменные окружения
│ ├── db/ # PostgreSQL, миграции, мастер админа
│ ├── db/ # PostgreSQL: подключение, миграции, репозитории
│ │ └── migrations/ # SQL-миграции (001_init.sql)
│ └── remnawave/ # API панели (users, squads)
├── Dockerfile # multi-stage сборка
├── docker-compose.yml # оркестрация
├── docker-compose.yml # bot + PostgreSQL (volume pgdata)
├── .env.example # шаблон переменных
├── .dockerignore
├── go.mod / go.sum