Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nestrilabs/nestri/llms.txt

Use this file to discover all available pages before exploring further.

Every Nestri runner — Steam, Heroic, and any custom image — is built on the runner-common base image. This image sets up the full streaming stack: GStreamer for video encoding, nestri-server for WebRTC delivery, supervisord for process management, PipeWire for audio, and a Wayland compositor with XWayland for application compatibility. You extend it with your application and set NESTRI_LAUNCH_CMD to tell the container what to run.

What runner-common provides

The base image installs and configures everything needed to capture and stream a desktop session:

nestri-server

The core streaming process. Captures the Wayland display, encodes video with GStreamer, and delivers it over WebRTC.

GStreamer stack

Full plugin set including VA-API, QSV, and WebRTC plugins for hardware-accelerated encoding on NVIDIA, AMD, and Intel GPUs.

Wayland compositor + XWayland

Gamescope provides the Wayland compositor. XWayland (xorg-xwayland) is also available for applications that require X11.

PipeWire audio

PipeWire, WirePlumber, and a virtual loopback device. Audio from your application is automatically captured and included in the stream.

supervisord

Manages all background services. Your application is launched as a supervisor-managed process alongside nestri-server.

GPU drivers

Vulkan, Mesa, and VA-API drivers for Intel, AMD, and NVIDIA are pre-installed. Bring your GPU via --gpus all or device passthrough.
The container runs as the nestri user (UID 1000) with access to the input, video, render, and seat groups. The home directory is /home/nestri.

Build a custom runner

1

Create a Containerfile

Start FROM the runner-common image and install your application. Set NESTRI_LAUNCH_CMD to the command that starts it.
Containerfile
ARG RUNNER_COMMON_IMAGE=ghcr.io/nestrilabs/nestri/runner-common:nightly

FROM ${RUNNER_COMMON_IMAGE}

# Install your application
RUN --mount=type=cache,target=/var/cache/pacman/pkg \
    pacman -S --noconfirm your-application && \
    paccache -rk1 && \
    rm -rf /usr/share/{info,man,doc}/*

# Set the launch command
ENV NESTRI_LAUNCH_CMD="your-application --some-flag"

# supervisord is the required entrypoint — do not change this
USER root
ENTRYPOINT ["supervisord", "-c", "/etc/nestri/supervisord.conf"]
Replace your-application with the package name and command for your app.
2

Build the image

docker build -t my-nestri-runner:latest .
3

Run the container

docker run -d \
  --name my-runner \
  --gpus all \
  -e RELAY_URL="ws://YOUR_RELAY_HOST:8088" \
  -e NESTRI_ROOM="my-custom-room" \
  -e RESOLUTION="1920x1080" \
  -e FRAMERATE="60" \
  --restart unless-stopped \
  my-nestri-runner:latest
4

Connect via the Nestri web app

Go to nestri.io, navigate to your session by room name, and click Play. Your application streams directly to the browser.

How NESTRI_LAUNCH_CMD works

The supervisord configuration at /etc/nestri/supervisord.conf reads NESTRI_LAUNCH_CMD and starts it as a managed process alongside nestri-server. You can override it at container runtime without rebuilding:
docker run -d \
  --name my-runner \
  --gpus all \
  -e NESTRI_LAUNCH_CMD="my-app --fullscreen" \
  -e RELAY_URL="ws://YOUR_RELAY_HOST:8088" \
  -e NESTRI_ROOM="my-room" \
  my-nestri-runner:latest
The application must stay in the foreground. If your command exits immediately (e.g., a shell script that forks and returns), supervisor will restart it in a loop. Use a wrapper script that blocks if needed.

Wayland and XWayland

runner-common sets up Gamescope as the Wayland compositor. Most modern Linux applications (GTK, Qt, Electron) support Wayland natively. For applications that only support X11, XWayland is available automatically — no extra configuration is needed. The DISPLAY and WAYLAND_DISPLAY environment variables are set by the entrypoint scripts.
If your application detects the wrong display server, you can force X11 mode by setting GDK_BACKEND=x11 or QT_QPA_PLATFORM=xcb in the container environment.

Windows games with Proton or Wine

Native Linux games work out of the box. For Windows games, you need to include a Proton or Wine runtime in your container.
Windows games require Wine or Proton. The runner-common base image does not include them. Add the runtime in your Containerfile.

Example: streaming a RetroArch setup

This example shows a complete custom runner for RetroArch — a multi-system emulator frontend that runs natively on Linux:
Containerfile
ARG RUNNER_COMMON_IMAGE=ghcr.io/nestrilabs/nestri/runner-common:nightly

FROM ${RUNNER_COMMON_IMAGE}

RUN --mount=type=cache,target=/var/cache/pacman/pkg \
    pacman -S --noconfirm retroarch retroarch-assets-xmb retroarch-assets-ozone && \
    paccache -rk1 && \
    rm -rf /usr/share/{info,man,doc}/*

# RetroArch config and ROMs can be mounted at runtime
VOLUME ["/home/nestri/.config/retroarch", "/home/nestri/roms"]

ENV NESTRI_LAUNCH_CMD="retroarch"

USER root
ENTRYPOINT ["supervisord", "-c", "/etc/nestri/supervisord.conf"]
Build and run:
docker build -t nestri-retroarch:latest .

docker run -d \
  --name nestri-retroarch \
  --gpus all \
  -v /path/to/retroarch-config:/home/nestri/.config/retroarch \
  -v /path/to/roms:/home/nestri/roms \
  -e RELAY_URL="ws://YOUR_RELAY_HOST:8088" \
  -e NESTRI_ROOM="retro-room" \
  nestri-retroarch:latest

Environment variables

VariableDefaultDescription
RELAY_URL(required)WebSocket URL of your relay node
NESTRI_ROOM(required)Unique room identifier for this session
NESTRI_LAUNCH_CMD(required)Command to launch your application
RESOLUTION1280x720Stream resolution (WxH)
FRAMERATE60Stream framerate (5–240)
VIDEO_CODECh264Video codec (h264, h265, av1)
VIDEO_BITRATE6000Target bitrate in kbps
VIDEO_BITRATE_MAX8000Maximum bitrate in kbps
VIDEO_ENCODER_TYPEhardwarehardware or software
GPU_VENDOR(auto)Select GPU by vendor (nvidia, amd, intel)
GPU_INDEX(auto)Select GPU by index

Troubleshooting

Your NESTRI_LAUNCH_CMD must block — the process must stay running. If your application forks into the background, write a wrapper script:
entrypoint.sh
#!/bin/bash
my-app --daemon
# Wait for the background process
wait $(pgrep -f my-app)
Set NESTRI_LAUNCH_CMD="bash /home/nestri/entrypoint.sh".
Check that your application uses Wayland or X11 (via XWayland). Some applications require an explicit display backend flag. Try setting WAYLAND_DISPLAY=wayland-0 or DISPLAY=:0 explicitly, and check the container logs for display connection errors.
Run winetricks to install common runtime dependencies (Visual C++ redistributables, DirectX, .NET Framework) into the Wine prefix. Many Windows applications need these before they will start.
Verify that PipeWire and WirePlumber are running:
docker exec my-runner supervisorctl status
Your application must output audio to PipeWire (the default on modern Linux). If it only supports PulseAudio, the pipewire-pulse shim included in runner-common should handle it transparently.

Next steps

Steam integration

Use the pre-built Steam runner for instant access to your Steam library.

Heroic Games Launcher

Stream Epic Games Store and GOG titles with the Heroic runner.

Streaming server configuration

Configure GPU selection, codecs, and encoding parameters.

Self-hosting overview

Full deployment guide including GPU driver setup.

Build docs developers (and LLMs) love