Docker image for running PeerTube Runner with NVIDIA acceleration for video transcoding and speech transcription tasks.
docker run -d --name peertube-runner-gpu \
--gpus all \
--restart unless-stopped \
-e PEERTUBE_RUNNER_URL=https://your-peertube-instance.com \
-e PEERTUBE_RUNNER_TOKEN=your_registration_token_here \
-e NVIDIA_DRIVER_CAPABILITIES=compute,video,utility \
-v peertube-runner-config:/home/runner/.config/peertube-runner-nodejs \
-v peertube-runner-cache:/home/runner/.cache \
bvdcode/peertube-runner-gpu:latest- NVIDIA CUDA 12.8.0 with cuDNN runtime on Ubuntu 24.04
- FFmpeg with NVENC wrapper for H.264 and H.265 transcoding
- Whisper-CTranslate2 transcription support
- Environment-variable or file-based runner configuration
- Runner process runs as a non-root user
- Automated image publishing to Docker Hub and GitHub Container Registry
vod-web-video-transcodingvod-hls-transcodingvod-audio-merge-transcodinglive-rtmp-hls-transcodingvideo-studio-transcodingvideo-transcriptiongenerate-video-storyboard
- Docker and Docker Compose
- NVIDIA Container Toolkit for GPU access
- NVIDIA driver compatible with CUDA 12.8
The container can start without a GPU if --gpus all is omitted. GPU transcoding and GPU transcription require the NVIDIA runtime.
Edit docker-compose.yml with your PeerTube URL and registration token, then run:
docker compose up -dThe compose file persists /home/runner/.config/peertube-runner-nodejs and /home/runner/.cache in named volumes. Keep these volumes unless you intentionally want to re-register the runner and re-download cached transcription models.
The compose file uses environment variables by default. To seed runner settings from a config file, copy config.example.toml to config.toml, edit it, and add ./config.toml:/home/runner/config.toml:ro to the existing volumes list. Keep PEERTUBE_RUNNER_URL and PEERTUBE_RUNNER_TOKEN set for first-time registration unless your persisted runtime config already contains a registered runner token.
For CPU-only use, remove the deploy.resources.reservations.devices section from docker-compose.yml.
| Variable | Default | Description |
|---|---|---|
PEERTUBE_RUNNER_URL |
Required | PeerTube instance URL |
PEERTUBE_RUNNER_TOKEN |
Required | PeerTube runner registration token |
PEERTUBE_RUNNER_NAME |
peertube-runner-gpu |
Runner name |
PEERTUBE_RUNNER_NAME_CONFLICT |
exit |
exit, auto, or wait |
PEERTUBE_RUNNER_CONCURRENCY |
2 |
Number of concurrent jobs |
PEERTUBE_RUNNER_FFMPEG_THREADS |
4 |
FFmpeg thread count |
PEERTUBE_RUNNER_FFMPEG_NICE |
20 |
FFmpeg process priority |
PEERTUBE_RUNNER_ENGINE |
whisper-ctranslate2 |
Transcription engine |
PEERTUBE_RUNNER_WHISPER_MODEL |
large-v3 |
Whisper model |
PEERTUBE_RUNNER_JOB_TYPES |
All jobs | Comma-separated job types |
PEERTUBE_RUNNER_DEBUG |
false |
Enable wrapper debug logs and runner verbose mode |
Example config.toml for runner settings:
[jobs]
concurrency = 2
[ffmpeg]
threads = 4
nice = 20
[transcription]
engine = "whisper-ctranslate2"
model = "large-v3"PeerTube Runner writes [[registeredInstances]] to its runtime config after successful registration. If you provide a fully registered config file yourself, use the runner token stored by PeerTube Runner, not the first-time registration token.
Persisting /home/runner/.config/peertube-runner-nodejs preserves that registered runner token across container recreates. Without a persistent config volume, each recreated container starts from a blank config and registers again.
PEERTUBE_RUNNER_NAME_CONFLICT controls behavior when the configured runner name already exists on the PeerTube instance:
exit: stop with an errorauto: append a timestamp to the runner namewait: retry every 30 seconds until the existing runner is removed
With auto, a 400 Bad Request response saying the runner name already exists is expected when the original name is already registered. The container then registers a timestamped runner name. This is useful for recovery, but a persistent config volume is the preferred way to keep one stable runner identity.
docker build -t peertube-runner-gpu .The PeerTube Runner npm package is pinned by the PEERTUBE_RUNNER_VERSION build argument.
docker build --build-arg PEERTUBE_RUNNER_VERSION=0.6.0 -t peertube-runner-gpu .bash scripts/smoke-test-image.sh peertube-runner-gpu
docker run --rm --gpus all --entrypoint nvidia-smi peertube-runner-gpudocker compose logs -f peertube-runner-gpu
docker compose ps
docker stats peertube-runner-gpu
docker exec peertube-runner-gpu nvidia-smiFor GPU issues, verify the host driver and Docker runtime:
nvidia-smi
docker run --rm --gpus all nvidia/cuda:12.8.0-runtime-ubuntu24.04 nvidia-smiFor registration issues, verify:
PEERTUBE_RUNNER_URLis reachable from the containerPEERTUBE_RUNNER_TOKENis a registration tokenPEERTUBE_RUNNER_NAMEis unique, orPEERTUBE_RUNNER_NAME_CONFLICTis set toautoorwait
If the container logs say it cannot create /home/runner/.config/peertube-runner-nodejs/default, update to the current image and recreate the container:
docker compose pull
docker compose up -d --force-recreateCurrent images repair persisted config and cache volume ownership before starting the runner process. Remove stale runner entries from the PeerTube admin UI if an older image had already registered timestamped runner names.
If a persisted runner entry is deleted from the PeerTube admin UI, keep PEERTUBE_RUNNER_TOKEN configured. The container can re-register after PeerTube rejects the stale persisted runner token.
bvdcode/peertube-runner-gpu:latestghcr.io/bvdcode/peertube-runner-gpu:latest