Installation¶
Automated Install
An interactive install script is available that handles all the steps below automatically:
Run it from the repository root on a fresh Debian/Ubuntu server.
Prerequisites¶
| Component | Version | Purpose |
|---|---|---|
| Ubuntu/Debian | 20.04+ / 11+ | Server OS |
| PHP | 8.1+ | Panel runtime |
| PHP Extensions | curl, mysqli, json, mbstring |
Required extensions |
| MariaDB/MySQL | 10.3+ / 5.7+ | Database |
| nginx | latest | Web server with PHP-FPM |
| Python | 3.8+ | DRM key acquisition |
| xaccel-codec | latest | Stream transcoding and DRM decryption |
| SSL certificate | — | HTTPS for the panel domain |
Step 1: Clone the Repository¶
The web root is the dazn.xctv.stream/ subdirectory inside the repo.
Create a symlink so nginx can serve it:
Step 2: Database Setup¶
Create the database and import the schema:
Or create the database manually:
Then import dazn-xctv.sql which creates all tables: settings,
sports, competition, competition_groups, epg_templates,
schedule, log, proxy, users, user_2fa_remember,
user_api_keys, tsdb_cache.
Step 3: Database Configuration¶
Edit dazn.xctv.stream/db.inc.php with your database credentials.
The file uses environment variables with fallback defaults:
$host = getenv('XCtv_dbHost') ?: '127.0.0.1';
$user = getenv('XCtv_dbUser') ?: 'dazn';
$password = getenv('XCtv_dbPass') ?: '';
$database = getenv('XCtv_dbName') ?: 'dazn';
Set environment variables in your PHP-FPM pool or .env file:
export XCtv_dbHost=192.168.1.85
export XCtv_dbUser=dazn
export XCtv_dbPass=YOUR_PASSWORD_HERE
export XCtv_dbName=dazn
Step 4: nginx Configuration¶
Copy the provided nginx config:
sudo cp /opt/xctv-dazn-drm-panel/etc/dazn.xctv.stream.conf /etc/nginx/conf.d/dazn.xctv.stream.conf
sudo nginx -t && sudo systemctl reload nginx
Before reloading, edit the config to match your environment:
- SSL certificate paths — update
ssl_certificateandssl_certificate_key - PHP-FPM socket — the config ships with
php8.1-fpm.sock; adjust to match your installed version (e.g.php8.3-fpm.sock) - Server name — change
dazn.xctv.streamto your domain
The config includes:
- Sensitive-path blocking —
.gitandpywidevine/requests return 404 - PHP-source protection —
db.inc.php,function.php, andauth.phpare routed through PHP-FPM - Clean API URL —
/apirewrites to/api.phpwithHTTP_AUTHORIZATIONforwarded - Extensionless PHP —
/footransparently rewrites to/foo.php - XML download — EPG files force download instead of browser rendering
Step 5: File Permissions¶
Use the included permissions script:
Or set manually:
sudo chown -R www-data:www-data /var/www/dazn.xctv.stream
sudo find /var/www/dazn.xctv.stream -type d -exec chmod 750 {} +
sudo find /var/www/dazn.xctv.stream -type f -exec chmod 640 {} +
sudo chmod 640 /var/www/dazn.xctv.stream/db.inc.php
The panel needs write access to:
| File | Purpose |
|---|---|
api_endpoints.json |
DAZN endpoint cache |
token.txt / refresh_token.txt |
Authentication tokens |
cron_dazn |
Generated cron entries |
xctv-dazn-epg.xml |
Generated EPG (filename configurable) |
Git revision display
The sidebar displays the current git revision by reading .git/HEAD
directly. Ensure www-data has read access to the .git/ directory.
Step 6: Python Dependencies¶
curl_cffi provides Chrome TLS fingerprint impersonation required for
DAZN Playback and license API calls (CloudFront WAF blocks standard
Python/cURL TLS fingerprints).
Step 7: Cron Jobs¶
The panel auto-generates per-event cron entries in /etc/cron.d/cron_dazn.
You need two system-level cron jobs:
# Build tomorrow's schedule at 23:58
58 23 * * * root /usr/bin/php /var/www/dazn.xctv.stream/cron_schedule.php
# Check and stop finished streams every 5 minutes
*/5 * * * * root /usr/bin/php /var/www/dazn.xctv.stream/reset_status.php
Initial Configuration¶
- Navigate to
https://dazn.xctv.stream/config_dazn - Enter your DAZN credentials (email/password)
- Set the xaccel-codec URL and token
- Configure CDN preferences in the
cdn_takesfield (JSON array) - Click Refresh API Endpoints from DAZN to populate endpoint cache
- Add sports and competitions via the sidebar, or use Discover IDs to scan from DAZN's EPG
Troubleshooting¶
| Symptom | Likely Cause | Fix |
|---|---|---|
| Token request error | Credentials wrong/expired | Update in Global Config |
| Empty schedule after cron | Endpoints stale or API changed | Click "Refresh API Endpoints" |
| NO CDN FOUND EXIT in log | cdn_takes doesn't match CDNs |
Check log for CDN names, update config |
| Stream starts, no video | DRM keys failed | Check request_keys.py connectivity |
| Playback 403 CloudFront | TLS fingerprint blocked | Ensure curl_cffi is installed |
| xaccel-codec "No decryption key" | Keys not applied | Check xaccel-codec supports dynamic-url API |
| PHP deprecation warnings | PHP 8.2+ ${var} syntax |
Fixed in v1.2.0 |