Skip to content

Installation

Automated Install

An interactive install script is available that handles all the steps below automatically:

sudo bash bin/install.sh

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

git clone git@git.retrorewind.ca:iptv/xctv-dazn-drm-panel.git /opt/xctv-dazn-drm-panel

The web root is the dazn.xctv.stream/ subdirectory inside the repo. Create a symlink so nginx can serve it:

sudo ln -s /opt/xctv-dazn-drm-panel/dazn.xctv.stream /var/www/dazn.xctv.stream

Step 2: Database Setup

Create the database and import the schema:

mysql -u root -p < dazn-xctv.sql

Or create the database manually:

CREATE DATABASE IF NOT EXISTS dazn
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_general_ci;

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_certificate and ssl_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.stream to your domain

The config includes:

  • Sensitive-path blocking.git and pywidevine/ requests return 404
  • PHP-source protectiondb.inc.php, function.php, and auth.php are routed through PHP-FPM
  • Clean API URL/api rewrites to /api.php with HTTP_AUTHORIZATION forwarded
  • Extensionless PHP/foo transparently rewrites to /foo.php
  • XML download — EPG files force download instead of browser rendering

Step 5: File Permissions

Use the included permissions script:

sudo bash /opt/xctv-dazn-drm-panel/bin/set-permissions.sh

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

cd /var/www/dazn.xctv.stream
pip3 install pywidevine protobuf requests curl_cffi

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

  1. Navigate to https://dazn.xctv.stream/config_dazn
  2. Enter your DAZN credentials (email/password)
  3. Set the xaccel-codec URL and token
  4. Configure CDN preferences in the cdn_takes field (JSON array)
  5. Click Refresh API Endpoints from DAZN to populate endpoint cache
  6. 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