Skip to main content

Documentation 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.

ErsatzTV Legacy is distributed as a Docker image hosted on the GitHub Container Registry at 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 is ghcr.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:
8409:8409
The UI and streaming port can be changed independently using environment variables (see below), but the standard single-port deployment is recommended unless you have a specific need to separate them.

Volume Mounts

ErsatzTV Legacy uses two container paths that you must account for:
PathPurpose
/configPersistent data — SQLite database (ersatztv.sqlite3), log files, secrets, artwork cache, search index, templates, and all generated configuration
/transcodeScratch space for live transcoding segments — should be a tmpfs mount for best performance
Your media library directories must also be bind-mounted into the container. Mount them read-only wherever possible to prevent accidental modification.
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

VariableDefaultDescription
TZSystem defaultHost timezone (e.g. America/Chicago, Europe/London). Controls the timezone used for schedule times and EPG generation.
ASPNETCORE_ENVIRONMENTProductionSet to Development to enable additional ASP.NET Core developer diagnostics. Leave as Production in normal use.
ETV_CONFIG_FOLDERPlatform data dirOverride the path where ErsatzTV stores its config and database. Set automatically to /config inside Docker.
ETV_TRANSCODE_FOLDERPlatform temp dirOverride 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_PORT8409Override the port the web UI listens on.
ETV_STREAMING_PORT8409Override 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_VULKAN1 (in image)Disables Vulkan in the NVIDIA pipeline. Enabled by default in the Docker image.
ETV_MAXIMUM_UPLOAD_MB10Maximum 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_SIZE10Number 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.
The base Compose file runs ErsatzTV Legacy with software transcoding. This is suitable for most installations and requires no special host configuration.
docker-compose.yml
services:
    ersatztv:
        image: ghcr.io/ersatztv/ersatztv:latest
        environment:
            TZ: America/Chicago
        ports:
            - "8409:8409"
        volumes:
            - ersatztv:/config
            #- /media/shared:/media/shared:ro
        tmpfs:
            - /transcode
volumes:
    ersatztv:
Uncomment and adjust the media volume mount (/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 prefer docker run over Compose, these commands cover the most common configurations:
docker run -d \
  --name ersatztv \
  -e TZ=America/Chicago \
  -p 8409:8409 \
  -v ersatztv:/config \
  --tmpfs /transcode \
  -v /media/shared:/media/shared:ro \
  ghcr.io/ersatztv/ersatztv:latest

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-arm64v8 as 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-arm32v7 as the .NET runtime base.
Hardware transcoding (NVIDIA/VAAPI) is not available on ARM. Software transcoding works on both ARM variants, though performance will depend heavily on the device’s CPU speed.

Upgrading

To upgrade to a newer image, pull the updated image and recreate the container. Docker Compose makes this straightforward:
docker compose pull
docker compose up -d
ErsatzTV applies any required database migrations automatically on startup. There is no separate migration step. Always back up your /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:
Another instance of ErsatztTV is already running.
This applies even if you start two separate containers sharing the same /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.

Build docs developers (and LLMs) love