This commit is contained in:
2026-05-04 00:45:21 +03:00
commit efcf3c7905
6 changed files with 289 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
# Nexuma
Nexuma is a multi-node VPN and proxy management platform. It lets you deploy VPN servers, manage users and subscriptions, and control everything from a single web interface.
## Features
- **Multi-node** — connect unlimited VPN servers, manage them from one place
- **Subscriptions** — per-user links with traffic limits, expiry, and auto-renewal
- **Multiple protocols** — VLESS, VMess, Trojan, Shadowsocks, Hysteria2, MTProto
- **Balance system** — user balance with deposits, withdrawals, and auto-charge on renewal
- **Traffic accounting** — per-subscription usage analytics
- **Telegram integration** — OAuth login, user approval flow, admin notifications
- **Routing rules** — xray-native rule sets and load balancers per node
- **Config builder** — guided wizard for protocol and stream configuration
- **Double VPN** — proxy chain support via node outbounds
- **External subscriptions** — aggregate external VPN share links into user subscriptions
## Architecture
```
┌───────────────────────────────────┐
│ Panel │
│ (Admin Web Interface) │
└────────────────┬──────────────────┘
┌────────────────▼──────────────────┐
│ Core │
│ (Control Plane API) │
│ PostgreSQL ◄────────► Redis │
└──────┬────────────────────────────┘
┌────┴──────────────┐
▼ ▼
Node 1 . . . Node N
```
## Quick Start
### 1. Deploy Core and Panel
Download [`docker-compose.base.yml`](./docker-compose.base.yml), fill in your values, and run:
```bash
docker compose -f docker-compose.base.yml up -d
```
Open `http://your-server:3010` — the first registered account becomes admin.
### 2. Deploy a Node
On each VPN server, download [`docker-compose.node.yml`](./docker-compose.node.yml).
1. In the admin panel, open **Nodes** and generate a registration code.
2. Set `CORE_URL` and `REGISTRATION_CODE` in the file.
3. Run:
```bash
docker compose -f docker-compose.node.yml up -d
```
The node registers with Core automatically on first start. After that, remove the `REGISTRATION_CODE` line.
## Documentation
- [Core](./core.md) — configuration and API reference
- [Node](./node.md) — setup and registration
- [Panel](./panel.md) — features overview
+59
View File
@@ -0,0 +1,59 @@
# Core
REST API server — the control plane of Nexuma. Manages users, tariffs, subscriptions, nodes, traffic accounting, and generates subscription configs for VPN clients.
## Configuration
Edit the environment variables in [`docker-compose.base.yml`](./docker-compose.base.yml):
| Variable | Required | Description |
|----------|----------|-------------|
| `DB_HOST` | Yes | PostgreSQL host |
| `DB_PORT` | Yes | PostgreSQL port |
| `DB_USER` | Yes | Database user |
| `DB_PASSWORD` | Yes | Database password |
| `DB_NAME` | Yes | Database name |
| `REDIS_HOST` | Yes | Redis host |
| `REDIS_PORT` | Yes | Redis port |
| `JWT_SECRET` | Yes | Access token secret |
| `JWT_REFRESH_SECRET` | Yes | Refresh token secret |
| `JWT_EXPIRES_IN` | No | Access token TTL (default: `15m`) |
| `JWT_REFRESH_EXPIRES_IN` | No | Refresh token TTL (default: `7d`) |
| `TELEGRAM_BOT_TOKEN` | No | Enables Telegram bot and OAuth login |
| `CORS_ORIGINS` | No | Allowed CORS origins (default: `*`) |
## API Overview
### Public
- `POST /auth/register` — create account
- `POST /auth/login` — login, get JWT tokens
- `POST /auth/refresh` — refresh access token
- `GET /sub/:uuid` — subscription config for VPN clients (base64 URI list)
- `GET /sub/:uuid/info` — subscription info (JSON)
- `GET /health`, `GET /metrics`
### User
- `GET /me` — profile and balance
- `GET /me/subscriptions` — subscriptions and links
- `GET /me/balance/transactions` — transaction history
### Admin
- **Users** — CRUD, status approval (pending / active / rejected), balance management
- **Tariffs** — CRUD
- **Nodes** — CRUD, protocol management, xray/MTProto version install, GeoIP update, outbounds
- **Subscriptions** — create, manage, auto-renewal toggle
- **Routing rule sets** — xray-native rules and balancers
- **External subscriptions** — aggregate external VPN share URLs
- **Audit logs**
## Tariff types
| Type | Expiry | Auto-renews |
|------|--------|-------------|
| Timed paid | By date | If balance ≥ 0 |
| Timed free | By date | Always |
| Indefinite paid | When traffic exhausted | If balance ≥ 0 |
| Indefinite free | When traffic exhausted | Always |
+70
View File
@@ -0,0 +1,70 @@
version: '3.9'
# Core + Panel deployment (main server)
# Usage: docker compose -f docker-compose.base.yml up -d
services:
redis:
image: redis:7-alpine
container_name: nexuma-redis
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- nexuma
core:
image: nexuma/core:latest
container_name: nexuma-core
restart: unless-stopped
environment:
PORT: 3000
# PostgreSQL — use an external instance or add a postgres service below
DB_HOST: your-postgres-host
DB_PORT: 5432
DB_USER: postgres
DB_PASSWORD: change-me
DB_NAME: nexuma
# Redis
REDIS_HOST: redis
REDIS_PORT: 6379
# JWT — use long random strings
JWT_SECRET: change-me
JWT_REFRESH_SECRET: change-me
JWT_EXPIRES_IN: 15m
JWT_REFRESH_EXPIRES_IN: 7d
# Optional: Telegram bot (enables OAuth login and notifications)
# TELEGRAM_BOT_TOKEN: your-bot-token
# CORS_ORIGINS: https://your-domain.com
ports:
- "3000:3000"
depends_on:
- redis
networks:
- nexuma
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:3000/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
panel:
image: nexuma/panel:latest
container_name: nexuma-panel
restart: unless-stopped
environment:
NUXT_CORE_URL: http://core:3000
ports:
- "3010:3000"
depends_on:
- core
networks:
- nexuma
volumes:
redis_data:
networks:
nexuma:
driver: bridge
+33
View File
@@ -0,0 +1,33 @@
version: '3.9'
# Node agent deployment (each VPN server)
# Usage: docker compose -f docker-compose.node.yml up -d
services:
node:
image: nexuma/node:latest
container_name: nexuma-node
restart: unless-stopped
environment:
PORT: 3001
# URL of Core — must be reachable from this server
CORE_URL: http://your-core-server:3000
# One-time registration code — generate in admin panel → Nodes
# Remove this line after the node registers successfully
REGISTRATION_CODE: your-one-time-code
HEARTBEAT_INTERVAL_SEC: 30
volumes:
- node_data:/var/lib/vpnnode
ports:
- "3001:3001"
cap_add:
- NET_ADMIN
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:3001/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
volumes:
node_data:
+30
View File
@@ -0,0 +1,30 @@
# Node
Agent that runs on each VPN server. Connects to Core, receives protocol configuration, manages the xray process, and reports traffic statistics.
## Configuration
Edit the environment variables in [`docker-compose.node.yml`](./docker-compose.node.yml):
| Variable | Required | Description |
|----------|----------|-------------|
| `CORE_URL` | Yes | URL of the Core service (e.g. `http://your-core-server:3000`) |
| `REGISTRATION_CODE` | Once | One-time code generated in admin panel → Nodes |
| `HEARTBEAT_INTERVAL_SEC` | No | Heartbeat interval in seconds (default: `30`) |
Data directory is `/var/lib/vpnnode` and mounted as a Docker volume — all state (auth key, VPN configs, binaries) persists across container restarts automatically.
## Registration
1. In the admin panel, open **Nodes** and generate a registration code.
2. Set `CORE_URL` and `REGISTRATION_CODE` in `docker-compose.node.yml`.
3. Run `docker compose -f docker-compose.node.yml up -d`.
4. Once the node appears as online in the panel, remove the `REGISTRATION_CODE` line.
## Behaviour
- Sends a heartbeat to Core every 30 seconds; if Core reports a newer config revision, the node pulls it immediately.
- Core can also trigger an instant config pull by calling the node directly (e.g. on admin-initiated sync).
- Reports per-subscription traffic to Core every minute.
- On first start, automatically installs the latest xray release if not present.
- Updates GeoIP/Geosite files automatically every 12 hours.
+30
View File
@@ -0,0 +1,30 @@
# Panel
Admin web interface for Nexuma. Built with Nuxt 3 and Nuxt UI.
## Configuration
| Variable | Required | Description |
|----------|----------|-------------|
| `NUXT_CORE_URL` | Yes | Internal URL of Core (e.g. `http://core:3000`) |
| `NUXT_PUBLIC_API_BASE` | No | Public API base path (default: `/api`) |
## Running
```bash
docker compose up -d
```
Open `http://your-server:3010`.
## What you can do
- **Users** — manage accounts, approve or reject registrations, top up balances
- **Tariffs** — create and configure tariff plans (protocols, nodes, traffic limits, price)
- **Nodes** — add VPN servers, configure protocols, install xray, manage routing
- **Subscriptions** — view and manage all subscriptions, create links, toggle auto-renewal
- **Config builder** — guided wizard to set up a new protocol on a node
- **Routing rules** — create xray rule sets and assign them to nodes
- **External subscriptions** — import external VPN share URLs into user subscriptions
- **Logs** — audit log viewer
- **User self-service** — users can view their own subscriptions, traffic, and balance