Contents

Compile Xray from Source — The Cleanest Way to Run a VLESS + REALITY Server on Linux

Subscribe to the Telegram Channel for the latest VPS deals and privacy-focused networking tips.

TL;DR

  • Build a portable, stripped xray binary from source using Go.
  • Deploy a minimal VLESS + REALITY inbound with a simple systemd unit.
  • Publish the guide on Hugo + LoveIt and serve via Cloudflare Pages with proper SEO metadata.

Target audience & intent

This guide is aimed at engineers and power users who want an auditable, minimal runtime for Xray. It focuses on Debian 12.9 examples and shows reproducible, copy-paste commands.


Prerequisites

  • A Debian 12.9 host (or compatible Debian family)
  • Basic familiarity with systemd, shell, and editing files over SSH
  • A small VPS for testing (example specs used in this guide: 1 vCPU, 768 MB RAM)

1. Install prerequisites

Update the system and install essential tools:

sudo apt update -y
sudo apt install -y git vim curl nano build-essential

Note: Avoid blind dist-upgrade on production hosts without testing.


2. Install Go (official binary)

Download and install the appropriate Go distribution for your CPU architecture.

Example for linux/amd64:

cd /opt
curl -LO https://go.dev/dl/go1.25.1.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.25.1.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version

If you run on ARM64, download the go1.25.1.linux-arm64.tar.gz archive instead.


3. Build Xray-core from source

Clone upstream and build a compact, portable binary.

git clone https://github.com/XTLS/Xray-core.git
cd Xray-core
go mod download

CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
sudo mv xray /usr/local/bin/
sudo chmod +x /usr/local/bin/xray

Why these flags?

  • CGO_ENABLED=0: disables cgo and reduces external dependencies.
  • -trimpath: removes local file system paths from the binary for reproducibility.
  • -ldflags "-s -w": strips debug symbols to reduce binary size.

4. Minimal VLESS + REALITY configuration

Create the configuration directory and file:

sudo mkdir -p /etc/xray
sudo nano /etc/xray/config.json

Paste the following minimal configuration and update the placeholders.

{
  "log": { "loglevel": "warning" },
  "inbounds": [
    {
      "port": 11983,
      "protocol": "vless",
      "settings": {
        "clients": [
          { "id": "YOUR-UUID-HERE", "flow": "xtls-rprx-vision" }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "dest": "www.bing.com:443",
          "serverNames": ["www.bing.com", "bing.com"],
          "privateKey": "YOUR-PRIVATE-KEY",
          "shortIds": ["YOUR-SHORTID-8HEX"]
        }
      },
      "sniffing": { "enabled": true, "destOverride": ["http","tls","quic"] }
    }
  ],
  "outbounds": [
    { "protocol": "freedom", "tag": "direct" },
    { "protocol": "blackhole", "tag": "block" }
  ]
}

Parameter generation:

  • UUID: xray uuid or uuidgen
  • PrivateKey (x25519): xray x25519
  • ShortID (8 hex): openssl rand -hex 8

5. systemd unit for process supervision

Create /etc/systemd/system/xray.service:

[Unit]
Description=Xray Service
Documentation=https://github.com/XTLS
After=network.target nss-lookup.target

[Service]
User=root
NoNewPrivileges=true
ExecStart=/usr/local/bin/xray run -config /etc/xray/config.json
Restart=on-failure
RestartPreventExitStatus=23

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable --now xray
sudo systemctl status xray --no-pager
sudo journalctl -u xray -n 80 --no-pager

6. Operational recommendations

  • Keep the xray binary in a private repository or artifact storage for reproducible deployments.
  • Use iptables/nftables to limit management access and reduce attack surface.
  • Rotate keys and short IDs periodically if you suspect compromise.
  • Test builds in an isolated staging environment before replacing production binaries.

7. Quick command reference

Action Command
Start sudo systemctl start xray
Stop sudo systemctl stop xray
Restart sudo systemctl restart xray
Status sudo systemctl status xray --no-pager
Logs sudo journalctl -u xray -n 80 --no-pager

8. Publish on Hugo + LoveIt (Cloudflare Pages)

Add the following front matter (already included at the top of this file). Suggested build settings for Cloudflare Pages:

  • Build command: hugo --minify
  • Publish directory: public
  • Enable automatic builds on main branch

LoveIt theme notes:

  • Set featured_image in front matter and add alt text.
  • Use the theme’s head partial to include Open Graph and Twitter Card metadata.

SEO checklist:

  • H1 once, descriptive H2 headings; include long-tail keywords naturally.
  • Add JSON-LD (TechArticle) and canonical URL.
  • Optimize images (WebP, 200 KB target) and enable Brotli on Cloudflare.

9. Troubleshooting (common errors)

  • permission denied — ensure /usr/local/bin/xray is executable and owned by root.
  • failed to bind port — port already in use; check ss -ltnp.
  • config parse error — validate JSON (use jq . /etc/xray/config.json).

References & further reading


Last updated: 2025-09-05