This commit is contained in:
2026-05-10 02:29:38 +03:00
parent efcf3c7905
commit 37b9a13d52
8 changed files with 1158 additions and 140 deletions
+161 -19
View File
@@ -1,30 +1,172 @@
# Node
Agent that runs on each VPN server. Connects to Core, receives protocol configuration, manages the xray process, and reports traffic statistics.
Node is the agent installed on each VPN/proxy server. It registers with Core, receives configuration revisions, applies local services, reports usage, and exposes authenticated runtime actions.
## Configuration
This page is public operator documentation. It describes setup, behavior, environment variables, Docker deployment, and the node HTTP API without requiring source-code access.
Edit the environment variables in [`docker-compose.node.yml`](./docker-compose.node.yml):
## Capabilities
| 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`) |
- One-time registration with Core.
- Persistent auth key storage.
- Config sync by revision.
- Xray install, restart, validation, GeoIP update, and key generation.
- MTProto install and restart.
- Nginx masking site management.
- System status reporting with CPU, RAM, disk, network, and process state.
- Heartbeat reporting.
- Per-user and per-subscription traffic reporting.
- Outbound traffic reporting for proxy chains.
- Session event reporting.
- Runtime error reporting.
- Crash watchdog for local services.
Data directory is `/var/lib/vpnnode` and mounted as a Docker volume — all state (auth key, VPN configs, binaries) persists across container restarts automatically.
## Environment Variables
| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `PORT` | No | `3001` | Local node agent HTTP port. |
| `NODE_ENV` | No | `development` | Runtime mode. |
| `CORE_URL` | Yes | `http://localhost:3000` | Core API URL reachable from the node server. |
| `REGISTRATION_CODE` | First start only | empty | One-time node registration code generated in the panel. |
| `NODE_AUTH_KEY` | No | empty | Optional fallback auth key when no key file exists. |
| `HEARTBEAT_INTERVAL_SEC` | No | `30` | Heartbeat interval in seconds. |
Persistent state is stored under `/var/lib/vpnnode`.
Keep this directory on a persistent Docker volume. It contains the auth key, generated configs, binaries, stats state, and masking-site files.
## Docker Compose
Create a `docker-compose.yml` on the VPN/proxy server:
```yaml
version: '3.9'
services:
node:
image: nexuma/node:latest
container_name: nexuma-node
restart: unless-stopped
environment:
PORT: 3001
CORE_URL: https://core.example.com
REGISTRATION_CODE: paste-one-time-code-here
HEARTBEAT_INTERVAL_SEC: 30
volumes:
- node_data:/var/lib/vpnnode
ports:
- "3001:3001"
# Add protocol ports here, for example:
# - "443:443"
# - "443:443/udp"
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:
```
Run:
```bash
docker compose up -d
```
After successful registration, remove `REGISTRATION_CODE` and redeploy:
```bash
docker compose up -d
```
## 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.
1. In the panel, open `Nodes`.
2. Generate a registration code.
3. Set `CORE_URL` and `REGISTRATION_CODE` on the node server.
4. Start the node container.
5. Wait until the node appears as registered.
6. Remove `REGISTRATION_CODE`.
7. Keep the `node_data` volume for future restarts.
## Behaviour
If the persistent volume is deleted, the node loses its auth key and must be registered again or started with `NODE_AUTH_KEY`.
- 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.
## Local HTTP API
Public:
| Method | Route | Purpose |
| --- | --- | --- |
| `GET` | `/health` | Health check. |
All other routes require `x-node-auth-key`.
| Method | Route | Purpose |
| --- | --- | --- |
| `GET` | `/node/status` | Runtime status and resource usage. |
| `POST` | `/node/apply-config` | Trigger config pull and apply. |
| `POST` | `/node/xray/restart` | Restart Xray. |
| `POST` | `/node/xray/install` | Install an Xray version. |
| `POST` | `/node/geoip/update` | Update GeoIP/geosite files. |
| `POST` | `/node/crypto/x25519` | Generate X25519 keys. |
| `POST` | `/node/crypto/mldsa65` | Generate an ML-DSA-65 seed. |
| `POST` | `/node/mtproto/restart` | Restart MTProto processes. |
| `POST` | `/node/mtproto/install` | Install an MTProto version. |
| `GET` | `/node/nginx/sites` | List masking sites. |
| `GET` | `/node/nginx/sites/:domain` | Get one masking site. |
| `PUT` | `/node/nginx/sites` | Replace masking sites. |
| `PUT` | `/node/nginx/site` | Upsert one masking site. |
| `GET` | `/node/nginx/site` | Get current masking site status. |
| `DELETE` | `/node/nginx/sites/:domain` | Delete one masking site. |
| `DELETE` | `/node/nginx/site` | Delete current masking site. |
| `POST` | `/node/nginx/restart` | Restart nginx. |
These endpoints are intended to be called by Core. Protect the agent port with firewall rules or private networking.
## Config Sync
- The node keeps the latest applied revision locally.
- Core can ask the node to apply config immediately.
- Heartbeat responses can also request sync.
- The node pulls the latest config from Core.
- If config apply succeeds, the node confirms the applied revision.
- If config apply fails, the node reports an error and keeps the previous valid config where possible.
## Traffic and Events
The node reports:
- user traffic
- subscription traffic attribution
- per-protocol usage
- outbound usage
- online/offline session events
- service crash and config errors
Traffic is flushed periodically. If reporting fails temporarily, the node keeps pending stats for the next flush where possible.
## Status Output
`GET /node/status` returns operational status including:
- system uptime
- CPU usage and core count
- RAM usage
- disk usage
- network transfer rates and totals
- Xray running state and uptime
- MTProto process state and connection counts
## Operations
- Use node sync from the panel after changing protocols, routing, or outbounds.
- Open every configured inbound port in Docker and the server firewall.
- Keep `/var/lib/vpnnode` persistent.
- Keep the node agent API private.
- Remove one-time registration codes after registration.
- Rotate auth keys when moving or rebuilding a server.