Skip to main content
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:
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: 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

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
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:

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