Docs

Getting started

From package to first channel. The operations guide and example configurations ship with the server under /usr/share/doc/alteoxms/.

Requirements

  • Linux x86-64. The server is a static Go binary; the bundled LGPL FFmpeg build needs glibc ≥ 2.39: Ubuntu 24.04+, Debian 13+, RHEL/Rocky/Alma 10, Fedora 40+. On older distributions use the Docker image.
  • For NVIDIA transcoding: driver R570 or newer (CUDA 12.8).
  • Outbound HTTPS to the license portal (not needed with an offline license).

Install

Debian / Ubuntu

sudo apt install ./alteoxms_<version>_amd64.deb
sudoedit /etc/alteoxms/config.json
sudo alteoxms -check-config
sudo systemctl start alteoxms        # enabled on install

RHEL / Rocky / Alma / Fedora

sudo dnf install ./alteoxms-<version>-1.x86_64.rpm
sudoedit /etc/alteoxms/config.json
sudo systemctl enable --now alteoxms

The packages install the server to /usr/bin/alteoxms, FFmpeg to /usr/lib/alteoxms/ffmpeg/, a hardened systemd unit, larger socket buffers for UDP/SRT ingest, and create the system user alteoxms. The configuration in /etc/alteoxms/ is never touched on upgrades.

Docker

docker run -d --name alteoxms --restart unless-stopped \
  -p 8080:8080/tcp -p 9000:9000/udp \
  -v /srv/alteoxms/etc:/etc/alteoxms \
  alteoxms:<version>

Mount the configuration directory read-write: changes made in the web UI or API are saved next to the file. For multicast use --network host (bridge networking does not forward multicast).

NVIDIA GPUs

  • Install the NVIDIA driver R570 or newer (production branch R570/R580); nvidia-smi must report CUDA 12.8 or higher. No CUDA toolkit is needed. Blackwell GPUs need the open kernel modules.
  • Docker: NVIDIA Container Toolkit ≥ 1.17, then docker run --gpus all ….
  • The server probes the hardware at startup (hardware: auto picks NVIDIA, then Intel QSV, then VAAPI, then CPU); a missing driver is reported, not fatal.
  • GPU capacity: the built-in model table is conservative; measure your GPU once and enter the values under gpu.models (operations guide, “GPU calibration”).

Activate the license

  1. Create an account with your company e-mail address and confirm it.
  2. Under Licenses, start the 7-day trial (once per company e-mail domain; free-mail addresses once per address) — or use a license issued by Alteox. Copy the key or download the .lic file.
  3. Open the server’s web UI (http://<server>:8080/ui/), accept the EULA in the setup step, and paste the key under License. For automated installs: server.license.accept_eula: true in the configuration and PUT /api/v1/license.

The server then holds a lease from the license portal, renewed every hour and valid for 72 hours — short network outages do not matter. Without a valid license the server keeps running (UI, API, inputs) but serves no viewers and no outputs.

  • Moving a server: release its seat under My servers, or call POST /api/v1/license/deactivate on the old server.
  • No internet: request an offline license on the Licenses page with the server fingerprints (fp_…, shown in the server’s web UI under License).
  • Clusters: every node takes a seat; clustering needs a Medium or Pro license.

Configuration basics

The configuration is one JSON file, /etc/alteoxms/config.json (YAML is accepted too). Everything you change in the web UI or the REST API is written back to it. Unknown keys are errors; syntax errors are reported with line and column.

{
  "server": { "http_listen": ":8080", "srt_listen": ":9000", "log_level": "info" },
  "api": {
    "keys": [ { "name": "automation", "sha256": "<hex SHA-256 of the key>", "role": "admin" } ]
  },
  "transcode_profiles": {
    "abr3": {
      "hardware": "auto",
      "video": [
        { "name": "1080p", "codec": "h264", "width": 1920, "height": 1080, "bitrate": "6000k", "gop": "2s" },
        { "name": "720p",  "codec": "h264", "width": 1280, "height": 720,  "bitrate": "3000k" },
        { "name": "480p",  "codec": "h264", "width": 854,  "height": 480,  "bitrate": "1200k" }
      ],
      "audio": [ { "tracks": "all", "codec": "aac", "bitrate": "128k", "channels": 2 } ],
      "subtitles": { "copy": true }
    }
  },
  "channels": [
    {
      "name": "sport1",
      "inputs": [
        { "url": "srt://encoder-a.example:9000?mode=caller&latency=200" },
        { "url": "udp://239.1.1.1:1234?iface=eth1" },
        { "url": "https://backup.example/sport1/index.m3u8" }
      ],
      "failover": { "loss_timeout": "2s", "return_after": "30s", "standby": "hot" },
      "transcode": "abr3",
      "outputs": {
        "srt": true,
        "http_ts": true,
        "hls": { "segment": "4s", "window": 6 },
        "dash": { "segment": "4s", "window": 6 }
      }
    }
  ]
}
  • Inputs are in priority order: the first is the primary, the others are backups (standby: hot keeps them connected).
  • transcode names a profile; omit it for passthrough.
  • Durations and bit rates are strings: "2s", "6000k".
  • Create an API key with alteoxms gen-key -name automation -role admin; it prints the key and the entry for api.keys.
  • Validate before you apply: alteoxms -check-config.

Playback: HLS at /sport1/index.m3u8, DASH at /sport1/manifest.mpd, HTTP MPEG-TS at /sport1/mpegts, SRT with streamid=read:sport1 on port 9000 — the channel page in the UI lists every URL.

Ports

PortProtocolPurpose
8080TCPHTTP-TS, HLS/DASH, REST API, web UI, /healthz, /metrics
9000UDPShared SRT listener (publish and read)
per channelUDPDedicated SRT ports, UDP/RTP inputs and outputs
7946TCPCluster: raft and node RPC (TLS), between nodes only

Put a TLS-terminating reverse proxy in front of 8080 for public HLS/DASH and the API, or set server.tls_cert / server.tls_key. Restrict the API and /metrics to management networks.

Reload, upgrade, logs

  • Reload without restart: systemctl reload alteoxms — validates first; an invalid file is rejected and the running configuration kept. Unchanged channels keep running.
  • Upgrade: install the new package; the service restarts, the configuration stays. Roll back by installing the previous version. For zero downtime, use a cluster and drain one node at a time.
  • Logs: journalctl -u alteoxms -f (structured; log_format: json for log shippers). Health: GET /healthz, GET /readyz, GET /api/v1/health.

Next steps