Files
vpn-proxy/.github/copilot-instructions.md

4.5 KiB

Project Guidelines

Overview

VPN-Proxy is a self-hosted VPN/proxy management system using sing-box as the core proxy engine (VLESS + REALITY TLS). It consists of a NestJS (TypeScript) backend, a vanilla HTML/JS frontend, PowerShell scripts for Windows management, and Docker for deployment. Documentation and UI are in Russian.

Architecture

Browser → NestJS web server (PORT, default 3456)
           ├─ Serves index.html with SSI-like includes (<!-- include "components/X.html" -->)
           └─ API endpoints in web/api/src/proxy/proxy.controller.ts
                 ↓ writes config
              data/client.json → sing-box binary (PROXY_PORT, default 8080)
                                    ↓ reload via HTTP to RELOAD_PORT (9090, internal)
                                    ↓
                              VPN traffic out

Key layers

Layer Location Notes
Frontend web/index.html, web/components/, web/static/ Tailwind via CDN, no build step
Backend web/api/ NestJS + TypeScript, minimal deps
Proxy core docker/entrypoint.sh + sing-box binary Config in data/client.json
Windows client manage.ps1, scripts/ PowerShell 7+ required, runs as Admin
Docker docker-compose.yml (dev), docker-compose.server.yml (prod, host network)

State files (data/)

All JSON. Do not change their structure without updating both backend and JS consumers:

  • client.json — active sing-box config
  • subscription.json — subscription URL + selected server
  • fallback.json — fallback proxy settings
  • proxy_enabled.json — on/off toggle
  • start_time.json — uptime timestamp
  • hwid — immutable device ID (16-char hex), generated once

Build and Run

# Docker (dev, bridged network)
docker compose up -d              # starts on localhost:3456 + 8080
docker compose up -d --build      # rebuild after changes

# Docker (Linux VPS, host network for UDP)
docker compose -f docker-compose.server.yml up -d

# Logs
docker logs -f sing-proxy

# Windows native (PowerShell 7, Admin)
.\manage.ps1

# Backend dev (local)
cd web/api
npm install
npm run start:dev

Environment variables: PORT (3456), PROXY_PORT (8080), RELOAD_PORT (9090), PROXY_BIND_IP (0.0.0.0).

Conventions

Code style

  • TypeScript: NestJS conventions — modules, controllers, services. camelCase for methods, PascalCase for classes
  • PowerShell: PascalCase functions (e.g., Write-Success, Manage-ScheduledTask)
  • JSON keys: camelCase (e.g., serverPort, selectedServer)
  • HTML element IDs: camelCase (e.g., subUrlInput, fallbackToggle)

Adding features

  • New API endpoint → controller in web/api/src/proxy/proxy.controller.ts + JS call in web/static/js/app.js
  • Business logic → web/api/src/proxy/proxy.service.ts
  • VLESS config changes → web/api/src/vless/vless.service.ts
  • Persistent state → web/api/src/storage/storage.service.ts (JSON file I/O)
  • Network utilities → web/api/src/network/network.service.ts
  • Windows scripts → scripts/setup-*.ps1, shared helpers in scripts/lib/

Backend module structure

web/api/src/
  main.ts              — Bootstrap & static assets
  app.module.ts        — Root module
  config/config.ts     — Environment configuration
  storage/             — JSON file persistence + HWID
  vless/               — VLESS URL parsing + sing-box config generation
  network/             — TCP latency + proxy performance measurement
  proxy/               — API controller + business logic service

VLESS handling

  • Parsing is strict: requires vless://uuid@host:port?pbk=...&sid=... format (REALITY params mandatory)
  • Subscription URLs must be http:// or https:// only

Pitfalls

  • Windows Docker cannot use network_mode: host — UDP (Discord voice, games) won't work in Docker on Windows. Use native sing-box via manage.ps1 instead.
  • Port 9090 is internal only — used for reload triggers via netcat, never expose externally.
  • hwid is immutable — after first generation, changing it requires manual file deletion.
  • DOS line endings — the Dockerfile runs dos2unix on shell scripts. Keep this in place.
  • sing-box needs a config before starting — apply config via the web UI first; it won't bootstrap empty.
  • No test suite exists — validate changes manually via Docker.
  • NestJS build required — the Dockerfile runs npm ci && npm run build during image build. For local dev use npm run start:dev.