# 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 () └─ 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 ```powershell # 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`.