cbb2133991
Users get Remnawave subscription via /config or inline button; TRIAL_USER_DAYS and panel lookup by Telegram ID. Co-authored-by: Cursor <cursoragent@cursor.com>
728 lines
26 KiB
Markdown
728 lines
26 KiB
Markdown
# tgvpn
|
||
|
||
**Версия:** [0.20.0](CHANGELOG.md)
|
||
|
||
Telegram-бот на Go для управления VPN через панель [Remnawave](https://docs.rw/): проверка панели, создание пользователей, назначение сквадов. Данные хранятся в **PostgreSQL**.
|
||
|
||
## Содержание
|
||
|
||
- [Требования](#требования)
|
||
- [Установщик (рекомендуется)](#установщик-на-сервере)
|
||
- [Быстрый старт](#быстрый-старт-docker-compose)
|
||
- [PostgreSQL](#postgresql)
|
||
- [Развёртывание на VPS](#развёртывание-на-vps-linux)
|
||
- [Обновление бота](#обновление-бота)
|
||
- [Переменные окружения](#переменные-окружения)
|
||
- [Админ-меню](#админ-меню-в-боте)
|
||
- [Устранение неполадок](#устранение-неполадок)
|
||
|
||
## Требования
|
||
|
||
| Компонент | Минимум |
|
||
|-----------|---------|
|
||
| Docker | 24+ |
|
||
| Docker Compose | v2 (`docker compose`) |
|
||
| PostgreSQL | 16+ (в compose включён) |
|
||
| Токен бота | [@BotFather](https://t.me/BotFather) |
|
||
| Сеть | Исходящий HTTPS к `api.telegram.org` (порт 443) |
|
||
|
||
Для запуска **без Docker**: Go 1.22+.
|
||
|
||
---
|
||
|
||
## Установщик на сервере
|
||
|
||
Интерактивный скрипт запросит все параметры, создаст `.env` и запустит Docker.
|
||
|
||
### Требования на сервере
|
||
|
||
- Linux (Ubuntu 22.04/24.04, Debian 12)
|
||
- `curl`, `git` (для клонирования)
|
||
- Права `sudo` (для установки Docker при необходимости)
|
||
|
||
### Установка одной командой
|
||
|
||
Если репозиторий уже на сервере:
|
||
|
||
```bash
|
||
cd tgvpn
|
||
chmod +x install.sh
|
||
./install.sh
|
||
```
|
||
|
||
Или скачайте скрипт и укажите каталог `/opt/tgvpn`:
|
||
|
||
```bash
|
||
sudo mkdir -p /opt/tgvpn
|
||
cd /opt/tgvpn
|
||
git clone <URL-вашего-репозитория> .
|
||
chmod +x install.sh
|
||
./install.sh
|
||
```
|
||
|
||
### Что спрашивает установщик
|
||
|
||
| Блок | Параметры |
|
||
|------|-----------|
|
||
| Telegram | `BOT_TOKEN`, `TELEGRAM_ADMIN_ID`, `BOT_DEBUG` |
|
||
| Remnawave | URL панели, API token, Caddy token, subscription URL |
|
||
| PostgreSQL | пользователь, база, пароль (можно сгенерировать случайный) |
|
||
| VPN | срок по умолчанию, UUID сквадов (опционально) |
|
||
| Система | каталог установки, URL git (если не из текущей папки) |
|
||
|
||
После завершения: `docker compose up -d --build`, проверка `docker compose ps`.
|
||
|
||
### Переменные окружения для PostgreSQL в compose
|
||
|
||
В `.env` должны совпадать `POSTGRES_PASSWORD` и пароль в `DATABASE_URL`:
|
||
|
||
```env
|
||
POSTGRES_USER=tgvpn
|
||
POSTGRES_PASSWORD=ваш_сильный_пароль
|
||
POSTGRES_DB=tgvpn
|
||
DATABASE_URL=postgres://tgvpn:ваш_сильный_пароль@db:5432/tgvpn?sslmode=disable
|
||
```
|
||
|
||
Установщик заполняет это автоматически.
|
||
|
||
---
|
||
|
||
## Быстрый старт (Docker Compose)
|
||
|
||
### 1. Клонирование
|
||
|
||
```bash
|
||
git clone <URL-вашего-репозитория>
|
||
cd tgvpn
|
||
```
|
||
|
||
### 2. Переменные окружения
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
Отредактируйте `.env`:
|
||
|
||
```env
|
||
BOT_TOKEN=ваш_токен_от_BotFather
|
||
BOT_DEBUG=false
|
||
TELEGRAM_ADMIN_ID=123456789
|
||
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
|
||
```
|
||
|
||
### 4. Проверка
|
||
|
||
```bash
|
||
# статус (db — healthy, bot — running)
|
||
docker compose ps
|
||
|
||
# логи бота (должно быть: «postgres ok», «бот @имя запущен»)
|
||
docker compose logs --tail=30 bot
|
||
|
||
# логи PostgreSQL
|
||
docker compose logs --tail=20 db
|
||
```
|
||
|
||
В Telegram: `/start` → кнопка «Получить конфиг» или `/config` (trial на `TRIAL_USER_DAYS`, по умолчанию 1 день). От админа — `/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.
|
||
|
||
### Шаг 1. Подключение к серверу
|
||
|
||
```bash
|
||
ssh user@your-server-ip
|
||
```
|
||
|
||
### Шаг 2. Установка Docker
|
||
|
||
```bash
|
||
sudo apt-get update
|
||
sudo apt-get install -y ca-certificates curl
|
||
sudo install -m 0755 -d /etc/apt/keyrings
|
||
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||
|
||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||
$(. /etc/os-release && echo "${VERSION_CODENAME}") stable" | \
|
||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
|
||
sudo apt-get update
|
||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||
sudo usermod -aG docker $USER
|
||
```
|
||
|
||
Выйдите из SSH и зайдите снова, чтобы группа `docker` применилась:
|
||
|
||
```bash
|
||
exit
|
||
ssh user@your-server-ip
|
||
docker --version
|
||
docker compose version
|
||
```
|
||
|
||
### Шаг 3. Клонирование проекта
|
||
|
||
```bash
|
||
sudo mkdir -p /opt/tgvpn
|
||
sudo chown $USER:$USER /opt/tgvpn
|
||
cd /opt/tgvpn
|
||
git clone <URL-вашего-репозитория> .
|
||
```
|
||
|
||
### Шаг 4. Настройка `.env`
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
nano .env # или vim / vi
|
||
```
|
||
|
||
Укажите реальный `BOT_TOKEN`, `DATABASE_URL` (в compose для VPS обычно оставляют `postgres://tgvpn:...@db:5432/...`), Remnawave и при необходимости UUID сквадов (`DEFAULT_*`).
|
||
|
||
Для продакшена смените пароль PostgreSQL — см. [PostgreSQL → Продакшен](#продакшен-смена-пароля-бд).
|
||
|
||
Права на секреты:
|
||
|
||
```bash
|
||
chmod 600 .env
|
||
```
|
||
|
||
### Шаг 5. Запуск в фоне
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Проверка:
|
||
|
||
```bash
|
||
docker compose ps
|
||
docker compose logs --tail=50 bot
|
||
docker compose logs --tail=20 db
|
||
```
|
||
|
||
### Шаг 6. Автозапуск после перезагрузки сервера
|
||
|
||
В `docker-compose.yml` уже указано `restart: unless-stopped`. После перезагрузки VPS контейнер поднимется сам, если Docker запущен:
|
||
|
||
```bash
|
||
sudo systemctl enable docker
|
||
sudo systemctl start docker
|
||
```
|
||
|
||
### Шаг 7. Обновление
|
||
|
||
См. раздел [Обновление бота](#обновление-бота) ниже.
|
||
|
||
---
|
||
|
||
## Обновление бота
|
||
|
||
Инструкция для уже работающей установки: подтянуть код из git, пересобрать контейнер и убедиться, что бот запустился.
|
||
|
||
### Перед обновлением
|
||
|
||
1. Убедитесь, что `.env` сохранён на сервере (он не в git).
|
||
2. Посмотрите, не появились ли новые переменные в `.env.example`:
|
||
|
||
```bash
|
||
cd /opt/tgvpn # или каталог, куда клонировали проект
|
||
git fetch origin
|
||
git diff HEAD origin/main -- .env.example
|
||
```
|
||
|
||
Если в `.env.example` есть новые строки — добавьте их в свой `.env` вручную.
|
||
|
||
### Обновление на VPS (Docker)
|
||
|
||
```bash
|
||
cd /opt/tgvpn
|
||
|
||
# 1. Скачать изменения
|
||
git pull origin main
|
||
|
||
# 2. Пересобрать и перезапустить (простой даунтайм ~10–30 сек)
|
||
docker compose up -d --build
|
||
|
||
# 3. Проверить логи
|
||
docker compose ps
|
||
docker compose logs --tail=50 bot
|
||
```
|
||
|
||
В логах должны быть строки вида: `бот @имя_бота запущен` и `администратор ID …`.
|
||
|
||
Проверка в Telegram (от аккаунта админа):
|
||
|
||
- `/start` — бот отвечает
|
||
- `/admin check` — проверка панели Remnawave
|
||
|
||
### Обновление на Windows (Docker Desktop)
|
||
|
||
```powershell
|
||
cd tgvpn
|
||
git pull origin main
|
||
docker compose up -d --build
|
||
docker compose logs --tail=50 bot
|
||
```
|
||
|
||
### Обновление без Docker (локально)
|
||
|
||
```bash
|
||
cd tgvpn
|
||
git pull origin main
|
||
go build -o bot .
|
||
# остановите старый процесс бота, затем:
|
||
./bot
|
||
```
|
||
|
||
### Если изменили только `.env`
|
||
|
||
Пересборка не нужна — достаточно пересоздать контейнер:
|
||
|
||
```bash
|
||
docker compose up -d --force-recreate
|
||
```
|
||
|
||
### Откат на предыдущую версию
|
||
|
||
```bash
|
||
cd /opt/tgvpn
|
||
git log --oneline -5 # найти нужный коммит
|
||
git checkout <хеш_коммита> # например: git checkout f360d53
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Вернуться на актуальную ветку:
|
||
|
||
```bash
|
||
git checkout main
|
||
git pull origin main
|
||
docker compose up -d --build
|
||
```
|
||
|
||
### Очистка старых образов Docker (опционально)
|
||
|
||
После нескольких обновлений на диске копятся неиспользуемые слои:
|
||
|
||
```bash
|
||
docker image prune -f
|
||
```
|
||
|
||
### Частые проблемы при обновлении
|
||
|
||
| Симптом | Решение |
|
||
|---------|---------|
|
||
| `git pull` конфликтует с локальными правками | `git stash` → `git pull` → `git stash pop` или сбросить локальные изменения: `git checkout -- .` |
|
||
| Бот не стартует после pull | `docker compose logs bot` — часто не хватает новой переменной в `.env` |
|
||
| Старый код в контейнере | Обязательно `--build`: `docker compose up -d --build` |
|
||
| Нет доступа к git | Проверьте SSH/HTTPS-доступ к вашему git-серверу |
|
||
|
||
---
|
||
|
||
## Развёртывание на Windows
|
||
|
||
### Docker Desktop
|
||
|
||
1. Установите [Docker Desktop](https://www.docker.com/products/docker-desktop/).
|
||
2. В PowerShell:
|
||
|
||
```powershell
|
||
git clone <URL-вашего-репозитория>
|
||
cd tgvpn
|
||
Copy-Item .env.example .env
|
||
# отредактируйте .env — вставьте BOT_TOKEN
|
||
docker compose up -d --build
|
||
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
|
||
go run .
|
||
```
|
||
|
||
или
|
||
|
||
```bash
|
||
go build -o bot .
|
||
./bot
|
||
```
|
||
|
||
---
|
||
|
||
## Переменные окружения
|
||
|
||
| Переменная | Обязательно | Описание |
|
||
|--------------|-------------|----------|
|
||
| `BOT_TOKEN` | да | Токен от @BotFather |
|
||
| `TELEGRAM_ADMIN_ID` | да | Числовой Telegram user ID администратора (например, [@userinfobot](https://t.me/userinfobot)) |
|
||
| `REMNAWAVE_PANEL_NAME` | нет | Название панели в админ-меню (по умолчанию «Панель 1») |
|
||
| `REMNAWAVE_PANEL_URL` | да | URL панели — сюда же идут запросы API (`/api/...`). Пример: `https://panel.example.com` ([док](https://docs.rw/docs/install/subscription-page/bundled)) |
|
||
| `REMNAWAVE_API_TOKEN` | да | Токен из **Remnawave Settings → API Tokens**, заголовок `Authorization: Bearer` |
|
||
| `CADDY_AUTH_API_TOKEN` | нет | `X-Api-Key`, если включён Caddy with security (как в оф. `.env` subscription-page) |
|
||
| `REMNAWAVE_SUBSCRIPTION_URL` | нет | Опционально: домен Subscription Page (`sub.*`), отдельная проверка |
|
||
| `DATABASE_URL` | да | PostgreSQL, в compose: `postgres://tgvpn:tgvpn@db:5432/tgvpn?sslmode=disable` |
|
||
| `TRIAL_USER_DAYS` | нет | Срок trial-конфига для `/config` (по умолчанию 1) |
|
||
| `DEFAULT_USER_DAYS` | нет | Срок при создании админом `/admin user` (по умолчанию 1) |
|
||
| `DEFAULT_EXTERNAL_SQUAD_UUID` | нет | External squad по умолчанию при быстром создании |
|
||
| `DEFAULT_INTERNAL_SQUAD_UUIDS` | нет | Internal squads через запятую |
|
||
| `BOT_DEBUG` | нет | `true` — подробные логи Telegram API (только для отладки) |
|
||
|
||
### Команды для пользователей
|
||
|
||
- `/start` — приветствие и кнопка получения конфига
|
||
- `/config` — создать пользователя в Remnawave на `TRIAL_USER_DAYS` (если активная подписка уже есть — вернёт существующую ссылку)
|
||
|
||
Нужны `DEFAULT_EXTERNAL_SQUAD_UUID` и `DEFAULT_INTERNAL_SQUAD_UUIDS` — те же сквады, что для быстрого `/admin user`.
|
||
|
||
### Админ-меню в боте
|
||
|
||
Только пользователь с `TELEGRAM_ADMIN_ID`:
|
||
|
||
- `/admin` — админ-меню (панель 1, Remnawave)
|
||
- `/admin check` — полная проверка: веб панели, API (статистика, users, nodes), подписка (settings + API), страница подписки
|
||
- `/admin config` — конфиг панели в боте
|
||
- `/admin user` — мастер создания пользователя в Remnawave + назначение сквадов
|
||
- `/admin user <логин> [дней]` — быстрое создание (сквады из `DEFAULT_*` в `.env`)
|
||
- `/admin squads` — список internal/external squads
|
||
- `/admin assign <логин>` — назначить сквады существующему пользователю
|
||
- Кнопки: «Создать пользователя», «Сквады», «Проверить панель», «Конфиг»
|
||
|
||
---
|
||
|
||
## Remnawave API (по официальной документации)
|
||
|
||
Как в [Bundled Subscription Page](https://docs.rw/docs/install/subscription-page/bundled):
|
||
|
||
```env
|
||
REMNAWAVE_PANEL_URL=https://panel.example.com
|
||
REMNAWAVE_API_TOKEN=API_TOKEN_FROM_REMNAWAVE
|
||
CADDY_AUTH_API_TOKEN=
|
||
```
|
||
|
||
- **Отдельного `REMNAWAVE_API_URL` нет** — API всегда на том же хосте, что и панель: `{REMNAWAVE_PANEL_URL}/api/...`
|
||
- Авторизация: `Authorization: Bearer {REMNAWAVE_API_TOKEN}`
|
||
- Внутри Docker-сети Remnawave: `REMNAWAVE_PANEL_URL=http://remnawave:3000`
|
||
- Домен `sub.*` — это Subscription Page, не панель; для API используйте `panel.*`
|
||
|
||
Пример проверки с сервера:
|
||
|
||
```bash
|
||
curl -s -o /dev/null -w "%{http_code}" \
|
||
-H "Authorization: Bearer $REMNAWAVE_API_TOKEN" \
|
||
"$REMNAWAVE_PANEL_URL/api/system/stats/recap"
|
||
```
|
||
|
||
---
|
||
|
||
## Полезные команды Docker
|
||
|
||
```bash
|
||
# пересобрать образ и перезапустить
|
||
docker compose up -d --build
|
||
|
||
# логи в реальном времени
|
||
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
|
||
|
||
# удалить контейнер и неиспользуемые образы проекта
|
||
docker compose down --rmi local
|
||
```
|
||
|
||
---
|
||
|
||
## Сеть и безопасность
|
||
|
||
- Бот использует **long polling**: входящие запросы на ваш сервер **не нужны**, порты открывать не требуется.
|
||
- Нужен только **исходящий** доступ к `https://api.telegram.org`.
|
||
- Не коммитьте `.env` в git. Не публикуйте `BOT_TOKEN` и пароль БД.
|
||
- PostgreSQL доступен **только внутри docker-сети** (порт наружу не проброшен по умолчанию).
|
||
- Контейнер бота запускается от непривилегированного пользователя `bot` (UID 10001).
|
||
|
||
Если позже добавите **webhook**, понадобится reverse proxy (nginx/Caddy), TLS и открытый порт 443 — это описывается отдельно при появлении функции.
|
||
|
||
---
|
||
|
||
## Устранение неполадок
|
||
|
||
### `BOT_TOKEN не задан` / `TELEGRAM_ADMIN_ID не задан`
|
||
|
||
- Проверьте, что файл `.env` лежит рядом с `docker-compose.yml`.
|
||
- В `.env` нет пробелов вокруг `=`: `BOT_TOKEN=123:ABC`, не `BOT_TOKEN = ...`.
|
||
- `TELEGRAM_ADMIN_ID` — только цифры, без `@username`.
|
||
- После правки: `docker compose up -d --force-recreate`.
|
||
|
||
### `Authentication failed` / `401 Unauthorized`
|
||
|
||
- Неверный или отозванный токен. Создайте новый в @BotFather → `/token` → обновите `.env` → `docker compose up -d --force-recreate`.
|
||
|
||
### Бот не отвечает в Telegram
|
||
|
||
```bash
|
||
docker compose ps # State должен быть running
|
||
docker compose logs bot # ошибки сети, токена
|
||
```
|
||
|
||
- Убедитесь, что на сервере нет блокировки Telegram (firewall, провайдер).
|
||
- Проверьте: `curl -I https://api.telegram.org` с хоста.
|
||
|
||
### API возвращает 502, веб-панель — 200
|
||
|
||
Частая причина: в `REMNAWAVE_PANEL_URL` указан домен **страницы подписки** (`sub.example.com`), а не **админ-панели** (`panel.example.com`).
|
||
|
||
1. Укажите URL **панели** (не sub): `REMNAWAVE_PANEL_URL=https://panel.example.com`
|
||
2. Токен API: `REMNAWAVE_API_TOKEN=...` (Settings → API Tokens)
|
||
3. Страницу подписки — опционально: `REMNAWAVE_SUBSCRIPTION_URL=https://sub.example.com`
|
||
4. Проверьте на сервере: `docker compose ps` (Remnawave Panel запущен), логи reverse proxy
|
||
|
||
### Контейнер постоянно перезапускается
|
||
|
||
```bash
|
||
docker compose logs --tail=200 bot
|
||
```
|
||
|
||
Чаще всего — пустой `BOT_TOKEN` или ошибка при старте.
|
||
|
||
### `DATABASE_URL не задан` / ошибки PostgreSQL
|
||
|
||
См. раздел [PostgreSQL → Ошибки](#ошибки-postgresql).
|
||
|
||
### Нет доступа к `docker` без sudo
|
||
|
||
```bash
|
||
sudo usermod -aG docker $USER
|
||
# перелогиньтесь
|
||
```
|
||
|
||
---
|
||
|
||
## Структура проекта
|
||
|
||
```
|
||
tgvpn/
|
||
├── main.go
|
||
├── internal/
|
||
│ ├── bot/ # Telegram, админ-меню, создание пользователей
|
||
│ ├── config/ # переменные окружения
|
||
│ ├── db/ # PostgreSQL: подключение, миграции, репозитории
|
||
│ │ └── migrations/ # SQL-миграции (001_init.sql)
|
||
│ └── remnawave/ # API панели (users, squads)
|
||
├── Dockerfile # multi-stage сборка
|
||
├── install.sh # интерактивный установщик на сервер
|
||
├── docker-compose.yml # bot + PostgreSQL (volume pgdata)
|
||
├── .env.example # шаблон переменных
|
||
├── .dockerignore
|
||
├── go.mod / go.sum
|
||
├── CHANGELOG.md
|
||
└── README.md
|
||
```
|
||
|
||
---
|
||
|
||
## Репозиторий
|
||
|
||
Укажите URL вашего приватного git-репозитория при клонировании.
|