ErsatzTV Legacy is distributed as a Docker image hosted on the GitHub Container Registry atDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ErsatzTV/legacy/llms.txt
Use this file to discover all available pages before exploring further.
ghcr.io/ersatztv/ersatztv. Running ErsatzTV Legacy in Docker is the recommended approach for most users — it bundles the correct FFmpeg build, Python runtime, and all required system libraries into a self-contained image that can be managed with Docker Compose.
Image
The published image isghcr.io/ersatztv/ersatztv. You can pin to a specific release tag (e.g. ghcr.io/ersatztv/ersatztv:26.6.0) or use latest to always pull the most recent release. The image is built on Ubuntu Noble and ships with a custom FFmpeg 7.1.1 build maintained by the ErsatzTV project (ghcr.io/ersatztv/ersatztv-ffmpeg:7.1.1).
Separate Dockerfiles exist for linux/amd64 (default), linux/arm64, and linux/arm/v7, so the image is multi-architecture and Docker will automatically select the correct variant for your host when pulling from the registry.
Port Mapping
ErsatzTV Legacy listens on port 8409 by default for both the web UI and the IPTV/streaming endpoints. Map this port to the same port on your host so that your media clients can reach the IPTV stream and EPG URLs directly:Volume Mounts
ErsatzTV Legacy uses two container paths that you must account for:| Path | Purpose |
|---|---|
/config | Persistent data — SQLite database (ersatztv.sqlite3), log files, secrets, artwork cache, search index, templates, and all generated configuration |
/transcode | Scratch space for live transcoding segments — should be a tmpfs mount for best performance |
Mounting
/transcode as tmpfs keeps transcoding scratch files in RAM. This dramatically reduces disk I/O during live streaming and avoids wear on SSDs. If you omit the tmpfs declaration, Docker will write segment files to a regular container layer, which is slower and accumulates data on restarts.Environment Variables
| Variable | Default | Description |
|---|---|---|
TZ | System default | Host timezone (e.g. America/Chicago, Europe/London). Controls the timezone used for schedule times and EPG generation. |
ASPNETCORE_ENVIRONMENT | Production | Set to Development to enable additional ASP.NET Core developer diagnostics. Leave as Production in normal use. |
ETV_CONFIG_FOLDER | Platform data dir | Override the path where ErsatzTV stores its config and database. Set automatically to /config inside Docker. |
ETV_TRANSCODE_FOLDER | Platform temp dir | Override the path used for transcoding scratch files. Set automatically to /transcode inside Docker. |
ETV_INSTANCE_ID | (unset) | A short identifier appended to channel IDs in XMLTV output. Set this when running multiple ErsatzTV instances so their EPG channel IDs do not collide in an aggregator like Channels DVR. |
ETV_UI_PORT | 8409 | Override the port the web UI listens on. |
ETV_STREAMING_PORT | 8409 | Override the port the IPTV streaming endpoint listens on. Defaults to the same value as ETV_UI_PORT. |
ETV_BASE_URL | (unset) | Set a URL base path when running behind a reverse proxy at a sub-path (e.g. /ersatztv). |
ETV_ALLOW_SHARED_PLEX_SERVERS | (unset) | Set to any non-empty value to allow connecting to shared (non-owned) Plex servers. |
ETV_DISABLE_VULKAN | 1 (in image) | Disables Vulkan in the NVIDIA pipeline. Enabled by default in the Docker image. |
ETV_MAXIMUM_UPLOAD_MB | 10 | Maximum file upload size in megabytes. Increase if you need to upload larger files through the web UI. |
ETV_SLOW_DB_MS | (unset) | Log a warning whenever a database query exceeds this threshold in milliseconds. Useful for diagnosing slow queries. Leave unset to disable. |
ETV_SLOW_API_MS | (unset) | Log a warning whenever an API request exceeds this threshold in milliseconds. Leave unset to disable. |
ETV_JF_PAGE_SIZE | 10 | Number of items fetched per page when scanning Jellyfin libraries. Reduce on low-memory devices if scanning causes memory pressure. |
ETV_JF_ENABLE_STATS | (unset) | Set to any non-empty value to enable Jellyfin playback statistics reporting. |
ETV_NEXT_FOLDER | (unset) | Override the folder path used by the ErsatzTV Next streaming engine. |
TRAKT__CLIENTID | (unset) | Your personal Trakt API application Client ID. Required if you want to sync Trakt lists. Create an app at trakt.tv/oauth/applications. |
NVIDIA_VISIBLE_DEVICES | (unset) | Required for NVIDIA GPU passthrough — set to all or a specific GPU index. |
NVIDIA_DRIVER_CAPABILITIES | (unset) | Required for NVIDIA GPU passthrough — set to compute,utility,video. |
Docker Compose Files
The repository ships three Compose files that can be layered together: a base file for the standard configuration and two overlay files for GPU acceleration variants.- Standard
- NVIDIA GPU
- VAAPI (Intel/AMD)
The base Compose file runs ErsatzTV Legacy with software transcoding. This is suitable for most installations and requires no special host configuration.Uncomment and adjust the media volume mount (
docker-compose.yml
/media/shared:/media/shared:ro) for each directory you want to make available to ErsatzTV. Mount media read-only (:ro) unless you have a reason to write to those paths from within the container.Quick-Start docker run Examples
If you preferdocker run over Compose, these commands cover the most common configurations:
ARM Support
ErsatzTV Legacy provides Dockerfiles for two additional ARM architectures:- ARM64 (linux/arm64) — suitable for Raspberry Pi 4/5, Apple Silicon (via emulation), and other 64-bit ARM single-board computers. Uses
mcr.microsoft.com/dotnet/aspnet:10.0-noble-arm64v8as the .NET runtime base. - ARM32v7 (linux/arm/v7) — suitable for older Raspberry Pi 3 models and other 32-bit ARMv7 devices. Uses
mcr.microsoft.com/dotnet/aspnet:10.0-noble-arm32v7as the .NET runtime base.
Upgrading
To upgrade to a newer image, pull the updated image and recreate the container. Docker Compose makes this straightforward:/config volume before upgrading.
Single-Instance Enforcement
ErsatzTV Legacy uses a named system mutex (Global\ErsatzTV.Singleton.74360cd8985c4d1fb6bc9e81887206fe) to prevent more than one instance from running concurrently. If a second instance is started while the first is already running, it will immediately exit with the message:
/config volume. Only one container should ever have the config volume mounted at a time. If you need multiple independent ErsatzTV instances (e.g. for separate channel lineups), give each instance its own dedicated config volume and set distinct ETV_INSTANCE_ID values so their EPG identifiers remain unique.