Self-hosted Xray proxy management for small teams. Push configs over SSH, detect config drift, and generate multi-format subscriptions from one embedded Go binary.
- Node lifecycle management for Xray Reality deployments
- Config drift detection with scheduled SHA256 comparisons
- User and group management for subscription access control
- Subscription generation with health-aware node selection
- SSH-based sync with atomic uploads and remote service reloads
- Single-binary deployment with the frontend embedded via
go:embed - Runtime system settings managed from the web UI and persisted in the database
Place screenshots in docs/screenshots/ with the following naming convention:
01-login.png02-dashboard.png03-users.png04-profiles.png05-settings.png06-subscribe.png
Recommended capture order:
- Login screen
- Dashboard overview
- User management
- Protocol configuration
- System settings
- Subscription portal
The current admin UI is primarily Chinese. Keeping
README.mdin English is still recommended for project discovery, while the screenshots and the Chinese manual provide localized context.
Secure access to the control panel with a lightweight sign-in screen, theme toggle, GitHub link, and clear operator-facing branding.
The dashboard highlights node health, active users, subscription delivery, recent operations, and the current control-plane status in a single view.
Manage subscription users, copy subscription links, open QR codes, assign groups, control expiration, and toggle access with consistent confirmation flows.
Define protocol templates, attach node-specific key material, and keep shared settings separate from node overrides for clearer operations.
Inspect runtime diagnostics, review deployment hints, and manage database-backed system settings without editing config files manually.
Render a browser-friendly subscription page with QR import, node-level copy actions, theme support, and smart fallback links while keeping client access on the same /sub/{token} endpoint.
| Layer | Technology |
|---|---|
| Backend | Go 1.26.1+, Gin, GORM, Zap |
| Database | SQLite by default, PostgreSQL optional |
| Auth | JWT bearer tokens, bcrypt |
| Crypto | AES-GCM for secrets at rest, SHA256 for drift checks |
| Frontend | React 19, Vite, TypeScript, Tailwind CSS v4 |
Linux amd64 and arm64 hosts can install the latest release with:
curl -fsSL https://raw.githubusercontent.com/imrui/xray-pilot/main/install.sh | sudo bashThe installer will:
- detect
amd64orarm64 - download the latest GitHub Release
- verify
checksums.txt - install
xray-pilotto/usr/local/bin/xray-pilot - create
/etc/xray-pilot/config.yaml - create
/etc/xray-pilot/ssh/for service-managed SSH keys - create and start the
xray-pilot.servicesystemd unit - generate a random admin password, JWT secret, and crypto master key
| Platform | Archive |
|---|---|
| Linux amd64 | xray-pilot_<version>_linux_amd64.tar.gz |
| Linux arm64 | xray-pilot_<version>_linux_arm64.tar.gz |
| macOS amd64 | xray-pilot_<version>_darwin_amd64.tar.gz |
| macOS arm64 | xray-pilot_<version>_darwin_arm64.tar.gz |
Manual installation steps:
- Download the matching archive and
checksums.txtfrom the latest GitHub Release. - Verify the archive with
sha256sum -c checksums.txt --ignore-missing. - Extract the binary and place it in your preferred location.
- Copy
config.yaml.exampletoconfig.yamland adjust the values. - Start the service with
./xray-pilot.
For fresh nodes, use scripts/node-bootstrap.sh to prepare SSH access, install Xray, and optionally enable BBR before adding the node to the panel.
Typical flow:
curl -fsSL https://raw.githubusercontent.com/imrui/xray-pilot/main/scripts/node-bootstrap.sh | sudo bashThe script supports interactive public-key input, or you can provide AUTHORIZED_KEYS up front for non-interactive usage:
curl -fsSL https://raw.githubusercontent.com/imrui/xray-pilot/main/scripts/node-bootstrap.sh | \
sudo AUTHORIZED_KEYS=$'ssh-ed25519 AAAA... admin@main\nssh-ed25519 AAAA... root@main' bashThe script creates a timestamped backup of sshd_config before changing PermitRootLogin.
Existing Linux installations can be upgraded by re-running the installer:
curl -fsSL https://raw.githubusercontent.com/imrui/xray-pilot/main/install.sh | sudo bashThe upgrade process will:
- replace
/usr/local/bin/xray-pilotwith the latest release binary - keep the existing
/etc/xray-pilot/config.yaml - keep the existing
/etc/xray-pilot/ssh/key directory - keep the existing SQLite database or external database settings
- reload and restart
xray-pilot.service
After the upgrade, you can confirm the running version with:
journalctl -u xray-pilot -n 20 --no-pagerPrerequisites: Go 1.26.1+, Node.js 24+
git clone https://github.com/imrui/xray-pilot.git
cd xray-pilot
make build
cp config.yaml.example config.yaml
# edit jwt.secret and crypto.master_key before first production run
./xray-pilotOpen http://localhost:2026 and sign in with the administrator account defined in config.yaml.
Copy config.yaml.example to config.yaml.
server:
port: 2026
mode: release
database:
driver: sqlite
dsn: xray-pilot.db
jwt:
secret: "change-me-use-a-long-random-string"
expire: 24
crypto:
master_key: ""
ssh:
default_port: 22
default_user: "root"
default_key_path: ""
known_hosts_path: "/var/lib/xray-pilot/known_hosts"
admins:
- username: admin
password: "change-me-now"For Linux service deployments, the recommended SSH key location is /etc/xray-pilot/ssh/id_ed25519. The service-owned known_hosts file is stored at /var/lib/xray-pilot/known_hosts.
Runtime settings such as scheduler intervals, SSH defaults, subscription formatting, and Xray log options are stored in the database-backed system settings table and managed from the web UI.
Environment variable override:
XRAY_PILOT_MASTER_KEY=<hex-key> ./xray-pilotPriority order:
XRAY_PILOT_MASTER_KEYconfig.yaml -> crypto.master_key- auto-generated key on first start
# backend
make dev-backend
# frontend
make dev-frontendThe frontend dev server proxies API requests to http://localhost:2026.
Pushing a tag named v* triggers GitHub Actions to:
- build the frontend with Node 24
- compile release binaries with Go 1.26
- package
tar.gzarchives for Linux and macOS onamd64andarm64 - generate
checksums.txt - publish a GitHub Release with all artifacts attached
MIT. See LICENSE.