weblinked

weblinked

Docker app from Stoatworks Labs' Repository

Overview

Renders a web page offscreen at a broadcast raster and exact frame rate and sends it out as NDI. Point it at a Grafana dashboard, a scoreboard, a lower third or a countdown clock and it becomes a video source your vision mixer, decoder or recorder can take. Chromium renders on the CPU through SwiftShader, so no GPU passthrough is needed. Measured at 50.1 ticks/sec at 1080p50 with zero dropped frames. IMPORTANT — the NDI runtime is not included and you must supply it. libndi is loaded at run time and its licence does not permit redistribution under MIT, so it cannot be shipped in the image. Download the NDI SDK for Linux from ndi.video, take libndi.so.6 out of lib/x86_64-linux-gnu/, put it in the "NDI runtime" path below, and restart the container. Without it everything still runs and the NDI output simply reports itself unavailable. This container uses host networking because NDI discovery is mDNS, which Docker's bridge network does not forward. In bridge mode the source is never seen by any receiver and nothing reports an error. SDI output is not available in a container: DeckLink and AJA need a card and a kernel driver on the host. Syphon and Spout are macOS and Windows only. The control page is at the WebUI link and is the whole interface — it also accepts HTTP and OSC from Companion or a show-control system. SECURITY: intended to run purely inside a private network or Tailscale tailnet. The control API has no authentication until you set an API token, and POST /api/script runs arbitrary JavaScript in the rendered page — so an open port here is remote code execution in a browser on your network, not just a feed a stranger can retune. Its security has not been independently reviewed by a human. Host networking puts the control port on every interface this server has, so set the bind address to your tailnet address, set an API token, and never expose it to the public internet.

[!IMPORTANT] This packaging has moved into WebLinked itself, under docker/, and the image is now published as ghcr.io/stoatworks-labs/weblinked — :edge from main, :X.Y.Z from each release, :sha-* per commit. The docs are docker/README.md.

ghcr.io/stoatworks-labs/weblinked-docker:edge no longer updates. It is frozen at a build of WebLinked as of 22 August 2026 (just after v1.0.1), and this repository is archived. Change any compose file or Unraid template to ghcr.io/stoatworks-labs/weblinked:edge.

AI-assisted project. This packaging was created with Claude (Anthropic), directed and reviewed by a human author. The NDI output has never been received from this image, because libndi is not in it and is not ours to ship.

weblinked-docker

[!WARNING] This is designed to run purely inside a Tailscale tailnet (or another private network you trust end to end). Do not expose it to the public internet. The control API has no authentication until you set --token, and POST /api/script runs arbitrary JavaScript in the rendered page — an unauthenticated port here is remote code execution in a browser on your network, not merely a feed someone can retune. Its security has not been independently reviewed by a human. This image binds 0.0.0.0 by default and runs with host networking, so it is on every interface the server has. Set WEBLINKED_BIND to your tailnet address, set a token, and keep it off the open internet. No reverse proxy, no port forward, no "it's fine, it has a password".

A URL in. NDI out. No display, no card, no desktop.

Moving to the new name

Change the image and nothing else — the mounts, ports, flags and WEBLINKED_* variables are the same:

-    image: ghcr.io/stoatworks-labs/weblinked-docker:edge
+    image: ghcr.io/stoatworks-labs/weblinked:edge

The NDI runtime is still yours to supply, mounted at /opt/ndi/lib, and host networking is still required for NDI discovery.

Why it moved

The Dockerfile here cloned WebLinked's main at build time, and that layer was a cache hit on every run — so :edge quietly stayed on WebLinked as of 22 August 2026, just after v1.0.1, through six releases. Built from WebLinked's own checkout, every change to the source reaches the image, and the image carries the version it was built from in its com.stoatworks.weblinked.version label.

Three things are different in the new image, all described in its README: the KMS and RTMP/SRT outputs are built off; the healthcheck now honours WEBLINKED_TOKEN, WEBLINKED_BIND and WEBLINKED_PORT; and the docs no longer claim mDNS discovery works in a container — this image never had avahi support, whatever this README used to say about mounting the avahi socket.

What is left here

The old Dockerfile, entrypoint and workflow, unchanged, the Unraid template under unraid/, and the history. The packaging is no longer developed here; issues belong on WebLinked.

Licence

MIT, matching WebLinked itself. NDI® is a registered trademark of Vizrt NDI AB (https://ndi.video); this project neither includes nor distributes any part of the NDI SDK.

Requirements

The NDI runtime is not bundled — see the note about libndi above. Everything else works without it.

Related apps

Details

Repository
ghcr.io/stoatworks-labs/weblinked-docker:edge
Last Updated2026-11-06
First Seen2026-08-10

Runtime arguments

Web UI
http://[IP]:7654/
Network
host
Shell
sh
Privileged
false