---
name: runpod-blender-desktop
description: Put a full Blender GUI desktop online in the browser on a rented RunPod GPU pod (xfce + TigerVNC + noVNC over the pod's HTTP proxy, password-protected), next to background bpy jobs for agents. Use when a team or AI agents need a shared remote Blender workstation without installing anything locally.
---

# Remote Blender desktop on a RunPod pod (browser, no local install)

Tested Oct 19 2026: Blender 5.2.1 LTS GUI running on an L40S pod, opened in a normal browser through RunPod's
HTTPS proxy, while AI agents ran headless `blender -b` / UniRig jobs over SSH on the same pod. The apt step took
~3 min; unpacking Blender onto a slow network volume took ~10 min more (see Pod choice).

## What you get, and what you don't
- A password-protected Linux desktop at `https://<podId>-<port>.proxy.runpod.net/vnc.html`, with Blender on the desktop.
- **The viewport is software-rendered** (Mesa llvmpipe; `glxinfo -B` reports `llvmpipe`). That's fine for inspecting
  rigs, weights and animation at modest poly counts, but sluggish on heavy scenes. Cycles renders can still use the GPU
  (CUDA/OptiX) from the GUI. Real GPU viewport acceleration needs VirtualGL, which is not covered here.
- The proxy URL is reachable by anyone who has it, so the VNC password is the only lock. Use a random one, keep it in a
  private file (chmod 600), and stop the pod when nobody is using the desktop.

## Ports
A pod's exposed ports are fixed at create time. Reuse one that already exists: the `runpod/comfyui` images expose
`8188/http` (ComfyUI), so kill ComfyUI and serve noVNC on 8188. For a new pod, include `8188/http` and `22/tcp` in
`ports`.

## Pod choice
- Image: `runpod/pytorch:2.4.0-py3.11-cuda12.4.1-devel-ubuntu22.04` booted in seconds. A large ComfyUI image sat 16 min
  without starting a container on one secure-cloud host.
- If `/workspace` is a network volume (`df` shows `mfs#...`), small-file writes are slow: the 380 MB Blender tarball
  took ~10 min to unpack. Blender on /workspace survives a stop; for a one-off pod, unpack to the container disk.
- Stopped pods often can't resume (`not enough free GPUs on the host machine`); expect to re-run this script on a new
  pod. Apt packages live on the container disk and are reinstalled after a stop; the script is idempotent.

## setup_desktop.sh (run ON the pod as a file, not as an inline ssh string; condensed from the tested script)
```bash
#!/usr/bin/env bash
# Usage: VNC_PASS=... bash setup_desktop.sh
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
BL_VER=5.2.1; BL_DIR=/workspace/blender/blender-${BL_VER}-linux-x64
if ! command -v vncpasswd >/dev/null || ! [ -d /usr/share/novnc ]; then
  apt-get update -qq
  apt-get install -y -qq --no-install-recommends xfce4 xfce4-terminal dbus-x11 x11-xserver-utils \
    tigervnc-standalone-server tigervnc-common tigervnc-tools novnc websockify \
    libxi6 libxxf86vm1 libxfixes3 libxrender1 libgl1 libegl1 libxkbcommon0 libsm6 libice6 xz-utils mesa-utils >/dev/null
fi
if ! [ -x "$BL_DIR/blender" ]; then
  mkdir -p /workspace/blender
  curl -fsSL --retry 3 https://download.blender.org/release/Blender5.2/blender-${BL_VER}-linux-x64.tar.xz | tar -xJ -C /workspace/blender
fi
ln -sf "$BL_DIR/blender" /usr/local/bin/blender
pkill -f 'ComfyUI/main.py' || true; sleep 1          # free port 8188
mkdir -p ~/.vnc
printf '%s\n' "${VNC_PASS:?set VNC_PASS}" | vncpasswd -f > ~/.vnc/passwd; chmod 600 ~/.vnc/passwd
cat > ~/.vnc/xstartup <<'X'
#!/bin/sh
unset SESSION_MANAGER DBUS_SESSION_BUS_ADDRESS
exec dbus-launch --exit-with-session startxfce4
X
chmod +x ~/.vnc/xstartup
mkdir -p ~/Desktop
printf '[Desktop Entry]\nType=Application\nName=Blender\nExec=%s/blender\nIcon=%s/blender.svg\n' "$BL_DIR" "$BL_DIR" > ~/Desktop/blender.desktop
chmod +x ~/Desktop/blender.desktop
vncserver -kill :1 >/dev/null 2>&1 || true
vncserver :1 -localhost yes -geometry 1920x1080 -depth 24 -SecurityTypes VncAuth >/workspace/desktop-vnc.log 2>&1
pkill -f 'websockify.*8188' || true
nohup websockify --web /usr/share/novnc 0.0.0.0:8188 localhost:5901 >/workspace/desktop-novnc.log 2>&1 &
sleep 2; ss -ltnp | grep -E ':8188|:5901'; blender -b --version | head -1; echo DESKTOP_READY
```
Copy it up with `scp`, write the password to a 600 file on the pod, and start it with
`VNC_PASS=$(cat /root/.vncpw) nohup bash setup_desktop.sh > /workspace/setup-desktop.log 2>&1 &`.

## Verify before telling anyone it works
1. `curl -s -o /dev/null -w "%{http_code}" https://<podId>-8188.proxy.runpod.net/vnc.html` returns 200.
2. Launch Blender on the display and screenshot the real desktop:
   `DISPLAY=:1 nohup blender &`, then `apt-get install -y imagemagick` and `DISPLAY=:1 import -window root shot.png`.
   Look at the image. Blender prints `GHOST/Wayland: XDG_RUNTIME_DIR not set` with a stack trace, then falls back to
   X11 and opens normally; check the process is still alive before calling it a crash.

## Traps we hit
- Ubuntu 22.04: `vncpasswd` is in **`tigervnc-tools`**, not the server package (`vncpasswd: command not found`).
- Don't chain the desktop setup and a long ML environment install in one background `bash -c`. Run them in parallel
  once apt is done, or one waits ~10 min on the other's download.
- `pkill -f 'bash -c VNC_PASS'` sent inline over ssh kills your own ssh shell (exit 255). Use bracket patterns
  (`'[b]ash run_all'`) or run kill logic from a script file on the pod.
- Agents and humans share one machine: give each agent its own output folder, serialize writes to shared .blend files,
  and keep a watchdog that stops the pod at a hard time limit. The pod bills until it is stopped, whether or not
  anyone is connected to the desktop.
