Docker deployment for Xray server
Server: VLESS + TLS + Let's Encrypt (Cloudflare API) + Cloudflare DNS + Xray Docker
Run this command on your server to install interactively:
bash <(curl -sSL https://raw.githubusercontent.com/openkikcoc/deployment-xray-server/main/install.sh)It will download files, guide you to configure .env, and start services automatically.
-
Clone or download this repo.
-
Copy the example environment file:
cp env.example .env
-
Edit
.envand fill in your details:DOMAIN: Your domain name (e.g.,vpn.example.com)CF_Token: Your Cloudflare API Token (with DNS:Edit permission)CF_Email: Your Cloudflare account emailUUID: A valid UUID (see below for generation methods)
Domain's DNS A Record should be configured in Cloudflare
How to generate UUID:
- macOS/Linux: Run
uuidgenin terminal - Python: Run
python3 -c "import uuid; print(uuid.uuid4())" - Online: Visit https://www.uuidgenerator.net/ or https://www.uuid.org/
- Windows PowerShell: Run
[guid]::NewGuid()
docker compose up -dThat's it!
- The
acmeservice will automatically issue a certificate and install it tocerts/server.crtandcerts/server.key. - The
xrayservice will wait for the certificates and then start automatically using the UUID provided in.env.
- Certificate Validity: Let's Encrypt certificates are valid for 90 days (3 months).
- Auto-Renewal: The
acmecontainer automatically checks and renews certificates every 12 hours. Certificates are typically renewed about 30 days before expiration. - No Manual Action Required: As long as the containers are running, certificates will be renewed automatically.
Run the helper script to generate client configurations (Shadowrocket link & Stash/Clash config):
./scripts/generate_client_config.shCopy the output to your client app.
install.sh: One-click installerdocker-compose.yml: Main deployment fileconfig/config.json: Xray config templatescripts/generate_client_config.sh: Client config generatorscripts/debug_server.py: Diagnosis tool (Server self-check & Client connection test)
If clients fail to connect despite a healthy server (verified by ./scripts/debug_server.py --mode server), firewalls might be blocking specific TLS fingerprints.
1. Simulate Chrome (Browser-like Handshake)
If this works but your client fails, enable uTLS (fingerprint: chrome) in your client.
openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} -alpn h2,http/1.12. Simulate Legacy Client
Tests basic connectivity without modern TLS features.
openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} -no_tls1_3Success = Verify return code: 0 (ok) / Failure = Connection reset