test: bump dotenv from 16.6.1 to 18.0.9 in /tests/e2e
XC_VM IPTV Panel
Open-source, community-driven Xtream Codes panel
Built for modern IPTV workflows – powerful, scalable, and free.
📑 Table of Contents
📘 Contents
🚀 Overview
XC_VM is an open-source IPTV platform based on Xtream Codes. It enables:
- 📺 Live & VOD streaming
- 🔀 Load balancing
- 📊 Full user/reseller control
- 🎚️ Transcoding & EPG
- 🔐 Hardened security fixes
✅ Free, AGPL-3.0. A single-server panel needs no key; load balancers and the fanout daemon need a free activation key — see Activation key.
⚠️ Status
BETA SOFTWARE — actively developed
📚 Documentation
-
🇬🇧 English Guide https://vateron-media.github.io/XC_VM/
-
🇷🇺 Руководство на русском https://vateron-media.github.io/XC_VM/ru/
🔄 Migration Guide
Migrating from Xtream Codes / XUI.one? Follow the step-by-step migration guide:
- 📖 Migration Guide https://vateron-media.github.io/XC_VM/latest/info/migration_guide/
🧱 Technology Stack
| Component | Version | Description |
|---|---|---|
| PHP | 8.3.36 | Backend runtime |
| Nginx | 1.24 | Web server & reverse proxy |
| FFmpeg | 8.0, 7.1, 4.0 | Media transcoding & processing |
| MariaDB | 11.4 | SQL database engine |
| KeyDB | 6.3.4 | Cache & session storage (Redis) |
| yt-dlp | latest | Resolves YouTube and other platform links |
| Deno | latest | JavaScript runtime yt-dlp needs for YouTube |
🐧 Supported Operating Systems
XC_VM supports multiple Linux distributions. Distribution-specific binaries are downloaded automatically during installation: PHP and Nginx from XC_VM_Binaries, FFmpeg from XC_VM_FFMPEG. yt-dlp is updated daily from its upstream releases, and Deno is installed from its upstream releases when missing.
Ubuntu
| Version | Codename | Status |
|---|---|---|
| 18.04 | Bionic Beaver | ❌ Not supported |
| 20.04 | Focal Fossa | ⚠️ Outdated — installation possible, but some packages may need to be installed manually |
| 22.04 | Jammy Jellyfish | ✅ Recommended |
| 24.04 | Noble Numbat | ✅ Recommended |
Debian
| Version | Codename | Status |
|---|---|---|
| 12 | Bookworm | ✅ Supported |
| 13 | Trixie | ✅ Recommended |
RHEL-compatible (Rocky Linux, AlmaLinux, CentOS, RHEL)
| Version | Status |
|---|---|
| 8 | 🚧 Not yet supported |
| 9 | 🚧 Not yet supported |
⚠️ RHEL-family support is planned but not yet available: there are no pre-built binaries or FFmpeg builds for it, and the installer refuses these distributions.
💡 Recommendations
For new installations:
- 🟢 Ubuntu 22.04 / 24.04 LTS
- 🟢 Debian 13
⚠️ Ubuntu 18.04 and Debian 11 are not supported: the installer warns on them and asks before going on.
📥 Quick Install
✅ Ubuntu 22.04+, Debian 12+
# 1. Update system
sudo apt update && sudo apt full-upgrade -y
# 2. Install dependencies
sudo apt install -y curl wget python3 unzip
# 3. Download latest release
latest_version=$(curl -s https://api.github.com/repos/Vateron-Media/XC_VM/releases/latest | grep '"tag_name":' | cut -d '"' -f 4)
wget "https://github.com/Vateron-Media/XC_VM/releases/download/${latest_version}/XC_VM.zip"
# 4. Unpack and install
unzip XC_VM.zip
sudo python3 install
🧪 Beta Install
To install the latest beta (pre-release) version:
# 1. Update system
sudo apt update && sudo apt full-upgrade -y
# 2. Install dependencies
sudo apt install -y curl wget python3-pip unzip
# 3. Download latest beta release
beta_version=$(curl -s https://api.github.com/repos/Vateron-Media/XC_VM/releases | grep -m1 '"tag_name":' | cut -d '"' -f 4)
wget "https://github.com/Vateron-Media/XC_VM/releases/download/${beta_version}/XC_VM.zip"
# 4. Unpack and install
unzip XC_VM.zip
sudo python3 install
⚠️ Beta versions may contain unstable features. Use on test servers only.
🧰 Service Management
sudo systemctl start xc_vm # Start
sudo systemctl stop xc_vm # Stop
sudo systemctl restart xc_vm # Restart
sudo systemctl status xc_vm # Status
sudo /home/xc_vm/bin/nginx/sbin/nginx -s reload # Reload Nginx config
journalctl -u xc_vm -f # Live logs
🔍 Troubleshooting — Panel Won't Start
If the panel fails to start, check the following logs and commands:
Nginx error log:
cat /home/xc_vm/bin/nginx/logs/error.log
PHP-FPM log:
cat /home/xc_vm/bin/php/var/log/php-fpm.log
Verify PHP binary works:
/home/xc_vm/bin/php/bin/php -v
If PHP fails to run, the panel cannot start at all — fix PHP issues first before investigating Nginx.
📂 Project Structure
├─ docs/ # 📚 Project documentation
├─ lb_configs/ # ⚙️ Configurations for building Load Balancer (LB)
└─ src/ # 💻 Main project code
🧮 Server Requirements & Sizing
🔧 Minimum Specs
| Component | Recommendation |
|---|---|
| CPU | 6+ cores (Xeon/Ryzen) |
| RAM | 16–32 GB |
| Disk | SSD/NVMe, 480+ GB |
| Network | Dedicated 1 Gbps port |
| OS | Ubuntu 22.04+, Debian 12+ (clean install) |
📊 Planning Formulae
- Bandwidth (Mbps) = Channels × Bitrate
- Max Users = Bandwidth ÷ Stream Bitrate
Example:
HD bitrate = 4 Mbps
1 Gbps = ~940 usable Mbps
→ Max Channels: 940 ÷ 4 = ~235
→ Max Users: 940 ÷ 4 = ~235
⚠️ 10 users watching the same channel = 10× bandwidth (unless caching or multicast used)
💻 RAM & CPU Usage
| Resource | Load per Stream |
|---|---|
| RAM | 50–100 MB |
| CPU (transcoded) | ~1 core |
Fanout RAM
With fanout delivery on, each online channel keeps one ring buffer that serves both the TS prebuffer and the HLS window, and all its viewers read from it, so RAM scales with channels, not clients:
- Ring seconds = max(Fanout HLS Window × Segment Time, Client Prebuffer + Segment Time), capped at 120 (defaults: max(6 × 6, 30 + 6) = 36 s)
- Fanout RAM ≈ Inbound (MB/s) × Ring seconds × 3
- The ×3 is the daemon's real overhead over raw stream data (Go heap headroom, GOP buffer capacity, recycled buffers), measured on a production LB
- A channel with no viewers for 30 s shrinks to ~50% of its ring (
Fanout Idle Buffer Grace/Fanout Idle Buffer Ratio) - Each client adds only socket/nginx buffers (a few MB at most for a slow viewer)
Rule of thumb (default settings): ~15 GB of RAM per 1 Gbps of inbound channels
Measured: 352 channels, ~2 Gbps inbound, 36 s ring
→ 250 MB/s × 36 s × 3 ≈ 27 GB (xc_fanout RSS: 29.2 GiB, ~85 MiB per channel)
→ the same with 10 or 1000 viewers
To shrink it, lower the ring: the larger of
Fanout HLS Window × Segment TimeandClient Prebuffer + Segment Timesets it, so lowering only one of them may change nothing.
✅ Features
- ✅ No server restrictions
- ✅ EPG importer
- ✅ VOD management
- ✅ User/reseller panel
- ✅ Security patches
- ✅ Clean UI
🔧 Known Limitations
- ❌ Requires Linux knowledge
- ❌ Community-based support
- ❌ Some bugs in transcoding module (in progress)
🤝 Contributing
We welcome community help!
⚠️ Legal & Project Independence Notice
XC_VM is an independent software project and is not affiliated with or endorsed by XUI.one.
All backend systems, core logic, and infrastructure of XC_VM have been independently developed without using source code from XUI.one or related projects.
The administrative interface (UI/UX) is inspired by general industry practices and partially by XUI.one in terms of usability concepts only. No proprietary source code or protected assets have been intentionally reused.
📜 License Enforcement (AGPL-3.0)
XC_VM is distributed under the GNU Affero General Public License v3.0 (AGPL-3.0).
Under this license:
- Redistribution or modification is permitted only under the same license (AGPL-3.0)
- Any modified version must remain open-source
- Providing XC_VM as a service requires making the source code available
- Copyright and attribution must be preserved
Any attempt to redistribute this software under a different license, remove attribution, or obscure the origin of the project constitutes a violation of the license terms.
Attribution-integrity check
As permitted by AGPL-3.0 §7(b) (preservation of author attributions), the panel
verifies on each request that its attribution notice — the "Vateron Media · AGPL-3.0"
credit shown in the panel footer — is still present. If the notice has been removed, the
management UI (admin / reseller / player panels) is locked with an
ATTRIBUTION_REMOVED notice until it is restored. The check is fully reversible and
non-destructive: no data is modified, the CLI remains available, and restoring the notice
unlocks the panel on the next request. End-viewer streaming is not affected by this check.
Each build is also stamped with a unique build identifier (XC_VM_BUILD_ID) for provenance,
so a leaked or rebranded copy can be traced back to the build it originated from.
Activation key
A single-server panel works without a key: the admin, reseller and player panels and streaming all run. Two capabilities are licensed, and need both the attribution intact and a valid activation key — neither replaces the other:
- load-balancer / cluster nodes — without a licence, new LB nodes cannot be added;
- the fanout delivery daemon — without a licence, live delivery falls back to the legacy path automatically (nothing is blocked, no data is touched).
Keys are issued free and self-service, one per installation (HWID, shown in Settings → Info and on the dashboard), and are revocable — this is accountability against rebranded resale, not monetization.
If a key expires or is revoked, the main server keeps working, and new LB nodes cannot be added until the key is renewed or replaced. Nodes already running are affected by how they connect:
- nodes that still hold the main server's database credentials (legacy, cluster modes 0–1): the main server revokes their database grant;
- API-only nodes (cluster mode 2) hold no database credentials: the main server stops
issuing leases, and each node keeps serving on the lease it already holds. It stops
when that lease runs out only if
lb_lease_fenceis on (off by default).
What the panel sends (full transparency)
A panel without a key makes no licensing requests until you enter one (entering a key
checks it immediately). A panel with a key contacts https://www.xcvm.tech only to:
(a) obtain its key (install_id), (b) re-check it once
a day and when you save or check it (jti, install_id, env_fp, nonce), and (c) send
one daily check-in from the main server (the same fields) recording which IP a HWID
runs from — evidence against a leaked copy. env_fp is a SHA-256 hash of the install ID,
/etc/machine-id and the hostname. Every response is Ed25519-signed and verified.
No stream data, viewer data, credentials, database or file contents are ever sent.
There is no remote command channel, but a signed "revoked" verdict does trigger the LB
response described above.
If the licensing server is unreachable, a key keeps working: offline for up to 14 days after issue until the server has confirmed it once, and with no time limit after that. Full detail: Licensing & Activation.
The xcvm_core extension
The panel source is AGPL-3.0. The bundled xcvm_core PHP extension is a separate,
closed-source binary under its own proprietary licence. It is written in Rust. It holds the module-delivery client (one archive, already
ionCube-encoded, inside a sealed envelope; there is no module key), the encrypted config /
database / Redis credential layer, the cluster API keys (including the signed, sealed
load balancer configs, XCVT v2) and the licence logic above, so that keys and credentials
never sit in readable PHP. Its whole behaviour is documented in
Core Extension. It
also refuses to load under a debugger (TracerPid != 0).
⚖️ You are solely responsible for how it is used. We take no responsibility for misuse or illegal deployments.