This project runs a virtual monitor (Xvfb), launches Chromium in kiosk mode on that virtual display, captures video + webpage audio, and streams it to YouTube Live via RTMPS.
docker-compose.yml— service definition and environment variablesDockerfile— container build instructionsstart.sh— starts Xvfb + PulseAudio + Chromium + FFmpeg
- Docker Engine
- Docker Compose plugin (
docker compose) - A YouTube Live stream key
If Docker is not installed, follow the official instructions for your OS:
- Docker Engine: https://docs.docker.com/engine/install/
- Docker Compose plugin: https://docs.docker.com/compose/install/
Use the official Docker APT repository to install both Docker Engine and the Compose plugin.
- Supported 64-bit Ubuntu versions: Jammy 22.04 (LTS), Noble 24.04 (LTS), Plucky 25.04, Questing 25.10
- Supported architectures:
x86_64 (amd64),armhf,arm64,s390x,ppc64le - Firewall note: Docker bypasses
ufw/firewalldfor published ports and is only compatible withiptables-nftoriptables-legacy. Use the DOCKER-USER chain for custom rules.
sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc | cut -f1)This may report that none are installed, which is fine. Existing Docker data in /var/lib/docker/ is not removed.
- Add Docker’s official GPG key:
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc- Add the Docker APT repository:
sudo tee /etc/apt/sources.list.d/docker.sources <<'EOF'
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update- Install Docker packages:
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginOptional: install a specific version instead of latest:
apt list --all-versions docker-ce
VERSION_STRING=5:29.1.3-1~ubuntu.24.04~noble
sudo apt install docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-pluginsudo systemctl status dockerIf not running:
sudo systemctl start dockerTest Docker Engine:
sudo docker run hello-worldTest Docker Compose:
docker compose versionsudo groupadd docker
sudo usermod -aG docker $USERLog out/in (or run newgrp docker) to apply group changes, then test:
docker run hello-world-
Clone or unzip this folder on the target machine.
-
Edit
docker-compose.ymland set:WEB_URLto the webpage you want to streamYT_STREAM_KEYto your YouTube Live stream key
-
Build and start the container:
docker compose up -d --build
-
Watch logs:
docker logs -f web2yt
-
Stop the stream:
docker compose down
You can adjust streaming quality or display settings via environment variables:
| Variable | Description | Default |
|---|---|---|
WEB_URL |
Webpage to render and stream | https://your-webpage.example.com |
YT_RTMPS_URL |
YouTube ingest URL | rtmps://a.rtmps.youtube.com/live2 |
YT_STREAM_KEY |
YouTube stream key | xxxx-xxxx-xxxx-xxxx |
WIDTH |
Capture width in pixels | 1920 |
HEIGHT |
Capture height in pixels | 1080 |
FPS |
Frames per second | 30 |
VIDEO_BITRATE |
FFmpeg video bitrate | 6500k |
VIDEO_MAXRATE |
FFmpeg max bitrate | 7500k |
VIDEO_BUFSIZE |
FFmpeg buffer size | 13000k |
AUDIO_BITRATE |
FFmpeg audio bitrate | 160k |
Default settings are tuned for mixed motion UI + voice:
VIDEO_BITRATE=6500k,VIDEO_MAXRATE=7500k,VIDEO_BUFSIZE=13000kAUDIO_BITRATE=160k
If CPU is high, try lowering to ~4500k and/or using -preset superfast (in start.sh).
If you have an NVIDIA GPU and want NVENC, replace the FFmpeg encode line in start.sh.
- Ensure
shm_size: "1g"is present (it is by default). - Try lowering resolution or FPS temporarily to debug.
- Ensure the webpage is actually playing audio (not muted).
- Inside the container:
pactl list short sinks pactl list short sources | grep virtSink.monitor
- Confirm Xvfb is running and
DISPLAY=:99:xdpyinfo -display :99 | head
Your YouTube stream key is sensitive. Keep docker-compose.yml private.