Skip to content

BEDOLAGA-DEV/bedolaga-cabinet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,558 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bedolaga Cabinet - Web Interface

Веб-интерфейс личного кабинета для VPN бота на базе Remnawave Bedolaga Telegram Bot V3.0.0+.

React + Vite + TypeScript | Авторизация через Telegram | Мультиязычность (EN/RU) | Адаптивный дизайн

Требования

  • Docker и Docker Compose
  • Запущенный backend бота с включенным Cabinet API
  • Обратный прокси (Caddy / Nginx / Traefik)

Архитектура

Браузер  →  Caddy/Nginx  →  /api/*     →  remnawave_bot:8080  (backend API)
                         →  /*          →  /srv/cabinet         (статика frontend)

Frontend — это статические файлы (HTML, JS, CSS). Обратный прокси выполняет две задачи:

  1. Раздает статику frontend
  2. Проксирует /api/* запросы на backend бота (с удалением префикса /api)

Установка

Шаг 1. Настройка backend бота

В .env файле бота добавьте:

# Включить Cabinet API
CABINET_ENABLED=true

# JWT секрет (сгенерируйте случайную строку: openssl rand -hex 32)
CABINET_JWT_SECRET=your_random_secret_key_here

# Разрешенные origins для CORS (домен, на котором будет кабинет)
CABINET_ALLOWED_ORIGINS=https://cabinet.example.com

Перезапустите бота после изменений.

Шаг 2. Получение frontend файлов

Вариант A: Готовый Docker образ (рекомендуется)

docker pull ghcr.io/bedolaga-dev/bedolaga-cabinet:latest

Извлеките собранные файлы из образа:

# Создать временный контейнер и скопировать статику
docker create --name tmp_cabinet ghcr.io/bedolaga-dev/bedolaga-cabinet:latest
mkdir -p ./cabinet-dist
docker cp tmp_cabinet:/usr/share/nginx/html/. ./cabinet-dist/
docker rm tmp_cabinet

Вариант B: Сборка из исходников

git clone https://github.com/BEDOLAGA-DEV/bedolaga-cabinet.git
cd bedolaga-cabinet
cp .env.example .env

Отредактируйте .env:

VITE_API_URL=/api
VITE_TELEGRAM_BOT_USERNAME=your_bot_username
VITE_APP_NAME=My VPN
VITE_APP_LOGO=V

Соберите и извлеките:

docker compose build cabinet-frontend
docker compose create cabinet-frontend
mkdir -p ./cabinet-dist
docker cp cabinet_frontend:/usr/share/nginx/html/. ./cabinet-dist/
docker compose rm -sf cabinet-frontend

Шаг 3. Размещение файлов на сервере

Скопируйте содержимое cabinet-dist в директорию, которую будет раздавать ваш прокси:

# Создайте директорию на сервере
sudo mkdir -p /srv/cabinet

# Скопируйте файлы (с локальной машины или напрямую на сервере)
sudo cp -r ./cabinet-dist/* /srv/cabinet/

Шаг 4. Настройка обратного прокси

Caddy (рекомендуется)

Caddy автоматически получает и обновляет SSL сертификаты.

https://cabinet.example.com {
    encode gzip zstd

    # API запросы → backend бота (удаляет /api префикс)
    handle /api/* {
        uri strip_prefix /api
        reverse_proxy remnawave_bot:8080
    }

    # Frontend статика
    handle {
        root * /srv/cabinet
        try_files {path} /index.html
        file_server

        # Кэширование статических ассетов (JS, CSS, шрифты, изображения)
        @static path *.js *.css *.woff *.woff2 *.ttf *.ico *.png *.jpg *.jpeg *.svg *.webp *.gif
        header @static Cache-Control "public, max-age=31536000, immutable"

        # HTML без кэша (для обновлений SPA)
        @html path *.html /
        header @html Cache-Control "no-cache, must-revalidate"
    }
}

Примечание: remnawave_bot:8080 — имя контейнера бота в Docker сети. Если Caddy запущен на хосте, а не в Docker, используйте localhost:8080 или IP сервера.

Nginx

server {
    listen 443 ssl http2;
    server_name cabinet.example.com;

    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    root /srv/cabinet;
    index index.html;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml image/svg+xml;

    # API запросы → backend бота
    location /api/ {
        rewrite ^/api/(.*) /$1 break;
        proxy_pass http://remnawave_bot:8080;
        proxy_http_version 1.1;
        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;
    }

    # Кэширование статических ассетов
    location ~* \.(?:js|css|woff2?|ttf|ico|png|jpe?g|svg|webp|gif)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # SPA fallback
    location / {
        try_files $uri /index.html;
        add_header Cache-Control "no-cache, must-revalidate";
    }
}

Шаг 5. Запуск и проверка

# Перезагрузите Caddy
docker exec <caddy_container> caddy reload --config /etc/caddy/Caddyfile

# Или Nginx
docker exec <nginx_container> nginx -s reload

Откройте https://cabinet.example.com в браузере.

Альтернативная установка: Docker контейнер с nginx внутри

Если вы не хотите раздавать статику напрямую, можно проксировать запросы на Docker контейнер cabinet.

docker-compose.yml

services:
  cabinet-frontend:
    image: ghcr.io/bedolaga-dev/bedolaga-cabinet:latest
    container_name: cabinet_frontend
    restart: unless-stopped
    # Порты НЕ пробрасываем — доступ только через Docker сеть
    networks:
      - bot_network

networks:
  bot_network:
    external: true
    name: remnawave-bedolaga-telegram-bot_bot_network  # Сеть вашего бота

Caddyfile

https://cabinet.example.com {
    encode gzip zstd

    # API запросы → backend бота
    handle /api/* {
        uri strip_prefix /api
        reverse_proxy remnawave_bot:8080
    }

    # Frontend → nginx контейнер (порт 80 внутри Docker сети)
    handle {
        reverse_proxy cabinet_frontend:80
    }
}

В этом варианте кэшированием статики занимается nginx внутри контейнера.

Переменные окружения

Build-time (вшиваются в JS при сборке)

Переменная Описание По умолчанию
VITE_API_URL Путь к API (/api или полный URL) /api
VITE_TELEGRAM_BOT_USERNAME Username Telegram бота (без @)
VITE_APP_NAME Название в шапке и вкладке браузера Cabinet
VITE_APP_LOGO Текст логотипа (1-2 символа) V

Runtime (только для Docker контейнера)

Переменная Описание По умолчанию
CABINET_PORT Порт контейнера на хосте 3020

Backend бота (.env бота)

Переменная Описание По умолчанию
CABINET_ENABLED Включить Cabinet API false
CABINET_JWT_SECRET Секретный ключ для JWT BOT_TOKEN
CABINET_ALLOWED_ORIGINS CORS origins (через запятую)
CABINET_ACCESS_TOKEN_EXPIRE_MINUTES Время жизни access token 15
CABINET_REFRESH_TOKEN_EXPIRE_DAYS Время жизни refresh token 7

Устранение проблем

CORS ошибка в консоли браузера

Домен кабинета не добавлен в CABINET_ALLOWED_ORIGINS в .env бота. Добавьте и перезапустите бота.

API возвращает HTML вместо JSON

Прокси настроен неправильно — запросы /api/* попадают на frontend вместо backend. Проверьте порядок блоков handle в Caddyfile (API должен быть первым).

502 Bad Gateway

  1. Backend бота не запущен — проверьте docker ps
  2. Контейнеры в разных Docker сетях — проверьте и подключите:
    # Проверить сети контейнера
    docker inspect <container> --format='{{json .NetworkSettings.Networks}}' | python3 -m json.tool
    
    # Подключить к нужной сети
    docker network connect <network_name> <container_name>
  3. Неправильное имя сервиса в прокси — проверьте через:
    docker exec <caddy_container> wget -qO- http://remnawave_bot:8080/health

Telegram авторизация не работает

  1. VITE_TELEGRAM_BOT_USERNAME должен быть без @
  2. Домен кабинета добавлен в BotFather → Bot Settings → Domain

Белый экран / SPA не работает

Прокси не настроен на fallback к index.html. Убедитесь что try_files {path} /index.html (Caddy) или try_files $uri /index.html (Nginx) присутствует в конфигурации.

Разработка

git clone https://github.com/BEDOLAGA-DEV/bedolaga-cabinet.git
cd bedolaga-cabinet
npm install
cp .env.example .env
# Отредактируйте .env
npm run dev

Dev-сервер запустится на http://localhost:5173 с автоматическим проксированием /api на localhost:8080.

Структура проекта

bedolaga-cabinet/
├── src/
│   ├── api/           # API клиенты (axios)
│   ├── components/    # React компоненты (UI kit)
│   ├── contexts/      # React контексты (auth, theme)
│   ├── hooks/         # Custom hooks
│   ├── locales/       # Переводы (i18n)
│   ├── pages/         # Страницы приложения
│   ├── types/         # TypeScript типы
│   └── utils/         # Утилиты
├── public/            # Статические файлы
├── Dockerfile         # Multi-stage сборка (node → nginx)
├── docker-compose.yml # Docker Compose для сборки
├── nginx.conf         # Nginx конфиг внутри контейнера
└── .env.example       # Пример переменных окружения

Связанные проекты

Контакты

Packages

 
 
 

Contributors

Languages