The real Xray VPN config held credentials and was overwritten by git checkout on every deploy. Untrack it + gitignore it + ship config.json.example as the template, so the server-side config persists across redeploys. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.0 KiB
Ingestion proxy (Xray / V2Ray) — for scanning Telegram etc. from Iran
The app's HttpClient can't speak vmess / vless / trojan directly. Instead, the Xray
sidecar (compose service xray) reads your config and exposes a plain SOCKS5 proxy at
xray:10808 (and HTTP at xray:10809) on the internal compose network. The app is then
pointed at that proxy from the admin panel, and only ingestion traffic goes through it.
[app ingestion] → socks5://xray:10808 → [Xray client] → vmess/vless/trojan → server → Telegram
Setup
-
Create your config from the example (it is git-ignored, so deploys never overwrite it):
cp deploy/xray/config.json.example deploy/xray/config.json nano deploy/xray/config.json # replace the `proxy` outbound with your vmess/vless/trojanKeep the
inboundsandroutingsections as-is so the local SOCKS/HTTP ports stay the same. -
Start the sidecar (it's behind a compose profile so normal deploys don't run it):
docker compose --profile proxy up -d xray docker logs hamkadr_xray --tail 30 # should show it listening, no errors -
Point the app at it: open
/Admin/Settings→ «کانالها/منابع» →- tick «ارسال جمعآوری از طریق پروکسی»
- set the proxy URL to
socks5://xray:10808 - Save, then run ingestion (Telegram source enabled).
-
Quick test the proxy reaches Telegram:
docker exec hamkadr_api sh -c "wget -q -O- --timeout=15 -e use_proxy=yes -e http_proxy=http://xray:10809 https://t.me/s/telegram | head -c 200" || true
Where to get the config values
If you have a share link (vmess://…, vless://…, trojan://…), import it into the Xray/v2rayN
client and export the JSON config, or decode it and fill the templates below.
vless + ws + tls (matches the default template in config.json)
{ "tag":"proxy","protocol":"vless","settings":{"vnext":[{"address":"HOST","port":443,
"users":[{"id":"UUID","encryption":"none"}]}]},
"streamSettings":{"network":"ws","security":"tls","tlsSettings":{"serverName":"SNI"},
"wsSettings":{"path":"/PATH","headers":{"Host":"SNI"}}} }
vmess + ws + tls
{ "tag":"proxy","protocol":"vmess","settings":{"vnext":[{"address":"HOST","port":443,
"users":[{"id":"UUID","alterId":0,"security":"auto"}]}]},
"streamSettings":{"network":"ws","security":"tls","tlsSettings":{"serverName":"SNI"},
"wsSettings":{"path":"/PATH","headers":{"Host":"SNI"}}} }
trojan + tls
{ "tag":"proxy","protocol":"trojan","settings":{"servers":[{"address":"HOST","port":443,
"password":"PASSWORD"}]},
"streamSettings":{"network":"tcp","security":"tls","tlsSettings":{"serverName":"SNI"}} }
Security note:
config.jsoncontains your VPN credentials. It's mounted read-only into the container. Do not commit a real config — keep the committed file as a placeholder and drop the real one on the server only (or add it to.gitignoreif you keep it locally).