Установка

Личный кабинет (WEBSITE)

Веб-кабинет для клиентов: просмотр подписки, оплата, управление устройствами. Модуль уже находится в файлах бота, но требует отдельной настройки и запуска.

Версия бота ? 3.4.5 Nginx + SSL ~20 минут
💡
Файлы модуля уже есть в папке бота — /root/bot/website/. Ничего скачивать дополнительно не нужно. Требуется только настроить .env, создать systemd-сервис и поднять прокси.
1

Требования

Сервер с ботом (основной)
Ubuntu 24.04 · Python 3.12 · Бот ? 3.4.5
Проксирующий сервер (отдельный VPS)
Ubuntu 20.04+ · Nginx · Certbot · Порты 80, 443
⚠️
Важно: WEBSITE нельзя разворачивать на одном сервере с ботом без прокси. Реальный IP бота должен быть скрыт — все запросы клиентов идут через проксирующий сервер, который перенаправляет их на бота.
💡
Для домена создайте A-запись, указывающую на IP проксирующего сервера, а не на сервер с ботом.
2

Настройка почты

Почта используется для отправки кодов подтверждения при входе клиентов. Поддерживаются два варианта:

Resend API (рекомендуется)
Работает через HTTPS, не требует открытых портов. Регистрация: resend.com
  • 1Создайте аккаунт и подтвердите домен
  • 2Создайте API-ключ
  • 3Укажите RESEND_API_KEY и SMTP_FROM в .env
SMTP (резервный вариант)
Используется если RESEND_API_KEY не задан. Подходит Gmail, Яндекс, свой сервер.
  • >Укажите SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM
⚠️
При использовании Resend: адрес отправителя SMTP_FROM должен быть на верифицированном домене. В тестовом режиме письма приходят только на ваш собственный email.
3

Настройка .env файла

Создайте или отредактируйте файл конфигурации на сервере с ботом:

bash
nano /root/bot/.env
/root/bot/.env
# -- Сессии ---------------------------------------------------------------
# Если пустой — сессии сбрасываются при каждом рестарте!
# Сгенерировать: python3 -c "import secrets; print(secrets.token_hex(32))"
WEBSITE_SESSION_SECRET=сгенерируйте_командой_выше

# -- Администратор ---------------------------------------------------------
# Секретный email для входа без кода. Если пусто — отключён.
WEBSITE_ADMIN_EMAIL=

# -- Почта -----------------------------------------------------------------
RESEND_API_KEY=re_xxxxxxxxxxxx
SMTP_FROM=noreply@ваш-домен.ru
# SMTP (используется если RESEND_API_KEY не задан)
# SMTP_HOST=smtp.example.com
# SMTP_PORT=465
# SMTP_USER=user@example.com
# SMTP_PASSWORD=password

# -- Адреса ----------------------------------------------------------------
SITE_URL=https://cabinet.ваш-домен.ru
XUIWEB_INTERNAL_URL=http://127.0.0.1:8282

# -- Поддержка -------------------------------------------------------------
SUPPORT_SITE=https://t.me/ваш_бот_поддержки
PRIVACY_URL=
TERMS_URL=

# -- Внешний вид -----------------------------------------------------------
# Тема для новых посетителей: light или dark
DEFAULT_THEME=dark

# -- Режим отдачи ключа ----------------------------------------------------
# happcrypto — ссылка шифруется, кнопка «Открыть в Happ»
# subscription — ссылка как есть, кнопка «Скопировать» для любого клиента
DEF_SUB_MODE=happcrypto

# -- Пробный период для регистраций через сайт -----------------------------
# 0 = отключено. Фактические дни берутся из настроек бота (trial_days)
TRIAL_DAYS=0
BOT_INTERNAL_URL=http://127.0.0.1:8081

# -- Telegram Login Widget -------------------------------------------------
# Имя бота без @ — добавляет кнопку «Войти через Telegram» на странице входа
# Требует /setdomain в BotFather
BOT_USERNAME=ваш_бот

# -- Мои устройства (требует запущенного SUBPAGE) --------------------------
WEBSITE_DEVICES_ENABLED=0

# -- Deep-link кнопки «Открыть в приложении» ------------------------------
# Варианты: happ://add/  incy://add/  v2raytun://import/
ADD_LINK=happ://add/

# -- Google OAuth (опционально) --------------------------------------------
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=

# -- Yandex OAuth (опционально) --------------------------------------------
# YANDEX_CLIENT_ID=
# YANDEX_CLIENT_SECRET=

# -- Отдельные реквизиты касс для сайта (опционально) ---------------------
# Если не заданы — используются настройки из БД (те же что у бота)
# WEBSITE_YOOKASSA_SHOP_ID=
# WEBSITE_YOOKASSA_SECRET_KEY=
# WEBSITE_PLATEGA_MERCHANT_ID=
# WEBSITE_PLATEGA_API_SECRET=

Справочник переменных

ПеременнаяОписание
WEBSITE_SESSION_SECRETКлюч подписи cookie-сессий. Без него сессии сбрасываются при каждом рестарте.Required
RESEND_API_KEYAPI-ключ Resend для отправки email-кодов входа.Optional
SMTP_FROMEmail отправителя (Resend или SMTP).Required
SITE_URLПубличный URL кабинета. Используется в реферальных ссылках.Required
XUIWEB_INTERNAL_URLВнутренний адрес xuiweb. По умолчанию http://127.0.0.1:8282.Optional
SUPPORT_SITEСсылка на поддержку в футере сайта.Optional
DEFAULT_THEMEТема для новых посетителей: light или dark.Optional
DEF_SUB_MODEhappcrypto — кнопка «Открыть в Happ». subscription — ссылка как есть, для любого VPN-клиента.Optional
TRIAL_DAYSПробный период для регистраций через сайт. 0 = отключено. Кол-во дней берётся из настроек бота.Optional
BOT_USERNAMEИмя бота без @. Добавляет кнопку «Войти через Telegram». Требует /setdomain в BotFather.Optional
WEBSITE_DEVICES_ENABLEDПоказывает раздел «Мои устройства» в кабинете. 1 = вкл. Требует запущенного SUBPAGE.Optional
ADD_LINKDeep-link кнопки «Открыть в приложении». Работает только при DEF_SUB_MODE=subscription.Optional
4

Виртуальное окружение и зависимости

bash · Сервер с ботом
# Переходим в папку сайта
cd /root/bot/website

# Создаём виртуальное окружение
python3 -m venv venv

# Устанавливаем зависимости
venv/bin/pip install -r requirements.txt
💡
pytailwindcss уже включён в requirements.txt — устанавливается автоматически. Сборка CSS запускается при каждом старте сервиса.
5

Systemd сервис

Создайте файл сервиса на сервере с ботом. Замените XX.XX.XX.XX на реальный IP вашего проксирующего сервера.

bash
nano /etc/systemd/system/website.service
ini · /etc/systemd/system/website.service
[Unit]
Description=VPN Website
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root/bot/website
ExecStart=/root/bot/website/venv/bin/uvicorn run:app \
    --host 0.0.0.0 \
    --port 3012 \
    --log-level info \
    --proxy-headers \
    --forwarded-allow-ips=XX.XX.XX.XX
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target
bash · Запуск и автозапуск
systemctl daemon-reload
systemctl enable website
systemctl start website
systemctl status website
⚠️
--forwarded-allow-ips должен содержать только IP вашего проксирующего сервера. Если указать * — любой сможет подделать свой IP через заголовок X-Forwarded-For.
6

Настройка UFW (файрвол)

Выполните на сервере с ботом. Порт 3012 открываем только для проксирующего сервера.

bash · Сервер с ботом
# SSH — обязательно до ufw enable!
ufw allow 22/tcp

# Порт сайта — только с IP проксирующего сервера
ufw allow from XX.XX.XX.XX to any port 3012

ufw --force enable
ufw status verbose
⚠️
Критично: выполните ufw allow 22/tcp до ufw enable, иначе SSH-соединение оборвётся и доступ к серверу будет потерян.
7

Проксирующий сервер — Nginx + SSL

Выполняется на отдельном VPS. Замените cabinet.ваш-домен.ru и IP-бота на реальные значения.

Установка Nginx и Certbot

bash · Проксирующий сервер
apt update && apt install -y nginx certbot python3-certbot-nginx

Получение SSL-сертификата

bash
certbot certonly --nginx -d cabinet.ваш-домен.ru

Конфиг Nginx

bash
nano /etc/nginx/conf.d/website.conf
nginx · /etc/nginx/conf.d/website.conf
server {
    listen 80;
    server_name cabinet.ваш-домен.ru;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name cabinet.ваш-домен.ru;

    ssl_certificate     /etc/letsencrypt/live/cabinet.ваш-домен.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cabinet.ваш-домен.ru/privkey.pem;

    location / {
        proxy_pass         http://IP-бота:3012;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_read_timeout 120s;
    }
}
bash · Проверка и перезагрузка
nginx -t && systemctl reload nginx
8

Активация в боте

  • 1Откройте веб-админку > Настройки > Основные
  • 2Найдите параметр show_website_button и установите значение 1
  • 3Сохраните настройки
💡
После активации в главном меню бота у пользователей появится кнопка «Личный кабинет», ведущая на сайт.
9

Проверка работоспособности

Статус сервиса
bash
systemctl status website
Логи в реальном времени
bash
journalctl -u website -f

Установка завершена

Кабинет https://cabinet.ваш-домен.ru
Страница входа https://cabinet.ваш-домен.ru/auth
9.1

Вход через Telegram (виджет)

Опционально. Добавляет кнопку «Войти через Telegram» на странице входа — пользователи могут авторизоваться без email.

Шаг 1 — Разрешить домен в BotFather
BotFather
/setdomain > выберите бота > введите домен без https:// и слэша

Пример: cabinet.ваш-домен.ru
Шаг 2 — Добавить переменную в .env
.env
BOT_USERNAME=myvpnbot
⚠️
Домен в BotFather должен совпадать с SITE_URL. Виджет работает только по HTTPS.