e7aa75b7baeaeec873ad1cef1dda2e18f19fceb1
VPN Control Panel
Система управления VPN-подписками: регистрация пользователей, тарифы, платежи, Telegram-бот, административная панель и фоновые задачи.
Стек
- Python 3.13 / FastAPI + Uvicorn
- SQLAlchemy 2 (async) + asyncpg
- PostgreSQL 16 / Redis 7
- Alembic — миграции БД
- aiogram 3 — Telegram-бот
- APScheduler — фоновые задачи
- Jinja2 — админ-панель
- Docker / Docker Compose
Структура
├── app/
│ ├── api/v1/ # REST API endpoints (users, payments, tariffs, servers, auth, stats)
│ ├── admin/ # Административная панель (Jinja2)
│ ├── bot/ # Telegram bot (handlers, middleware, dispatcher)
│ ├── models/ # SQLAlchemy ORM модели
│ ├── providers/ # VPN-провайдеры (абстракция + Mock)
│ ├── repositories/ # Слой доступа к данным (CRUD)
│ ├── scheduler/ # Фоновые задачи (APScheduler)
│ ├── schemas/ # Pydantic схемы запросов/ответов
│ ├── services/ # Бизнес-логика
│ └── utils/ # Вспомогательные функции
├── docker/
│ ├── Dockerfile # Production-сборка
│ ├── Dockerfile.dev # Dev-сборка
│ └── entrypoint.sh # Точка входа (миграции + uvicorn)
├── migrations/ # Alembic миграции
├── tests/ # Тесты
├── .env.example
├── docker-compose.yml
└── docker-compose.dev.yml
Быстрый старт
1. Запуск через Docker (рекомендуется)
cp .env.example .env
# Отредактируйте .env (BOT_TOKEN, JWT_SECRET и т.д.)
docker compose up -d
Приложение будет доступно на http://localhost:8000.
2. Локальный запуск для разработки
# Только БД и Redis
docker compose -f docker-compose.dev.yml up -d
# Python окружение
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.dev.txt
# Миграции
alembic upgrade head
# Запуск
uvicorn app.main:app --reload --port 8000
Миграции
Создание новой миграции:
alembic revision --autogenerate -m "description"
Применение миграций:
alembic upgrade head
Откат на одну:
alembic downgrade -1
Создание администратора
Администратор создаётся напрямую в БД. Telegram ID — ваш числовой ID в Telegram.
docker compose exec app python -c "
import asyncio
from app.database import async_session_factory
from app.repositories.admin import AdminRepository
from app.models.admin import AdminRole
async def create():
async with async_session_factory() as session:
repo = AdminRepository(session)
admin = await repo.create(
telegram_id=123456789, # Ваш Telegram ID
username='admin',
role=AdminRole.SUPERADMIN,
is_active=True,
)
print(f'Admin created: id={admin.id} tg={admin.telegram_id}')
asyncio.run(create())
"
Настройка Telegram
- Создайте бота через @BotFather, получите токен.
- Укажите токен в
.env:BOT_TOKEN=ваш_токен. - Узнайте свой Telegram ID (например, через @userinfobot).
- Добавьте его в БД через скрипт выше.
- Запустите — бот ответит на команды только администраторам из БД.
Команды бота:
/start — приветствие
/help — список команд
/users — список активных пользователей
/user <id> — информация о пользователе
/delete <id> — деактивация пользователя
/renew <id> — статус подписки
/expired — список просроченных подписок
/expiring [N] — истекают в ближайшие N дней (по умолч. 3)
/stats — статистика системы
Пример .env
APP_NAME=VPN Control Panel
DEBUG=false
PORT=8000
POSTGRES_USER=vpn
POSTGRES_PASSWORD=vpn_secret
POSTGRES_DB=vpn_control
POSTGRES_HOST=db
POSTGRES_PORT=5432
REDIS_URL=redis://redis:6379/0
BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
ADMIN_IDS=[123456789]
ADMIN_GROUP_ID=-1001234567890
ADMIN_GROUP_THREAD_ID=
JWT_SECRET=случайная_строка_32_символа
JWT_ACCESS_EXPIRE_MINUTES=30
JWT_REFRESH_EXPIRE_DAYS=30
OUTLINE_API_PREFIX=https://example.com:1234/abc123
OUTLINE_CERT_SHA256=sha256hash...
Пример API
Авторизация:
# Логин (secret_key = JWT_SECRET из .env)
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"telegram_id": 123456789, "secret_key": "change_me_to_random_string"}'
# Ответ:
# {"access_token": "...", "refresh_token": "...", "token_type": "bearer"}
Пользователи:
# Список (требуется Bearer token)
curl http://localhost:8000/api/v1/users \
-H "Authorization: Bearer <access_token>"
# Создать
curl -X POST http://localhost:8000/api/v1/users \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"telegram_id": 987654321, "username": "user", "full_name": "User Name"}'
Тарифы:
curl http://localhost:8000/api/v1/tariffs
# [{"id":1,"name":"Basic","duration_days":30,"price":500.0,"currency":"RUB",...}]
Платежи:
curl -X POST http://localhost:8000/api/v1/payments \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"user_id": 1, "tariff_id": 1, "amount": 500, "provider": "manual"}'
# Подтвердить платёж (активирует подписку)
curl -X PATCH http://localhost:8000/api/v1/payments/1/confirm \
-H "Authorization: Bearer <access_token>"
Статистика:
curl http://localhost:8000/api/v1/stats
# {"total_users":5,"active_users":3,"total_revenue":2500.0,...}
Административная панель:
http://localhost:8000/admin/ — Dashboard
http://localhost:8000/admin/users — Пользователи
http://localhost:8000/admin/payments — Платежи
http://localhost:8000/admin/servers — Серверы
http://localhost:8000/admin/tariffs — Тарифы
Healthcheck:
curl http://localhost:8000/health
# {"status":"ok","database":"connected"}
Документация API (Swagger):
http://localhost:8000/docs
http://localhost:8000/redoc
Архитектура
Client → FastAPI (REST / Admin)
↓
Service Layer
↓
Repository Layer
↓
PostgreSQL / Redis
↓
Telegram Bot ← aiogram ← APScheduler (daily tasks)
- Service Layer — бизнес-логика, не содержит SQL.
- Repository Layer — только CRUD, без логики.
- Сервисы не вызывают друг друга — оркестрация на уровне handler.
- Telegram-бот не содержит бизнес-логики — только отображение.
- Scheduler не содержит Telegram-кода — только вызовы сервисов.
Планы
- WireGuard / Outline / XRay провайдеры
- Онлайн-оплата (ЮKassa, Stripe)
- Рассылка уведомлений
- Dashboard с графиками
Лицензия
MIT
Description
Languages
Python
86.5%
HTML
12.6%
Dockerfile
0.4%
Mako
0.4%
Shell
0.1%