Headless NVIDIA on CentOS/RHEL 6: VirtualGL 2.6 + TurboVNC 2.2 (Working Guide)

VirtualGL + TurboVNC on CentOS 6 with headless NVIDIA Xorg (:0)

Headless NVIDIA + VirtualGL + TurboVNC on CentOS/RHEL 6 (EOL): A Working Guide

Why this post? CentOS/RHEL 6 are end-of-life, so current docs often break. This guide shows a known-working setup for running OpenGL apps over the network with VirtualGL 2.6.x and TurboVNC 2.2.x on headless NVIDIA GPUs (Tesla-era), including the critical NV-GLX / GLXCreateContext fixes.

Versions that still work on CentOS 6

  • VirtualGL: 2.6.x (e.g., 2.6.5-20201117) — 3.x requires newer glibc.
  • TurboVNC: 2.2.x (e.g., 2.2.90-20211222) — 3.x requires newer glibc and libXfont2.
  • NVIDIA driver: 390.xx is a practical ceiling for many Fermi/Tesla cards.

Enable the VirtualGL & TurboVNC repos

Create two repo files (adjust baseurls if yours differ):

[root@host ~]# cat >/etc/yum.repos.d/VirtualGL.repo <<'EOF'
[VirtualGL]
name=VirtualGL
baseurl=https://virtualgl.org/pmwiki/uploads/Downloads/CentOS/6/x86_64
enabled=1
gpgcheck=0
EOF

[root@host ~]# cat >/etc/yum.repos.d/TurboVNC.repo <<'EOF'
[TurboVNC]
name=TurboVNC
baseurl=https://turbovnc.org/pmwiki/uploads/Downloads/CentOS/6/x86_64
enabled=1
gpgcheck=0
EOF

Install specific (compatible) versions

# VirtualGL 2.6.x (works on CentOS 6)
yum install -y VirtualGL-2.6.5-20201117

# TurboVNC 2.2.x (newer 3.x requires GLIBC_2.16+ and libXfont2)
yum install -y turbovnc-2.2.90-20211222

# 3D + fonts + GLX utilities
yum install -y xorg-x11-server-Xorg xorg-x11-xauth xorg-x11-xinit glx-utils \
               xorg-x11-fonts-misc xorg-x11-fonts-Type1 mesa-libGL mesa-dri-drivers

Configure a headless NVIDIA X server on :0

  1. Find Bus IDs:
    nvidia-smi -pm 1
    nvidia-smi -q | egrep -i 'Bus Id|Bus'
    # Example GPU0 = 0000:02:00.0 → BusID "PCI:2:0:0"
  2. Write /etc/X11/xorg.conf (headless NoScanout):
    cat >/etc/X11/xorg.conf <<'EOF'
    Section "ServerFlags"
        Option "DontVTSwitch" "true"
        Option "AllowEmptyInitialConfiguration" "true"
    EndSection
    
    Section "Device"
        Identifier  "GPU0"
        Driver      "nvidia"
        BusID       "PCI:2:0:0"
        Option      "UseDisplayDevice" "None"
        Option      "AllowEmptyInitialConfiguration" "true"
    EndSection
    
    Section "Monitor"
        Identifier  "DummyMon0"
        HorizSync   28.0-80.0
        VertRefresh 48.0-75.0
    EndSection
    
    Section "Screen"
        Identifier "Screen0"
        Device     "GPU0"
        Monitor    "DummyMon0"
        DefaultDepth 24
        SubSection "Display"
            Depth 24
            Virtual 1920 1080
        EndSubSection
    EndSection
    
    Section "Files"
        ModulePath "/usr/lib64/xorg/modules"
    EndSection
    
    Section "Module"
        Load "glx"
    EndSection
    
    Section "ServerLayout"
        Identifier "Layout0"
        Screen  "Screen0"
    EndSection
    
    Section "DRI"
        Mode 0666
    EndSection
    EOF
  3. Make sure X loads NVIDIA’s GLX (not Mesa’s):
    ls -l /usr/lib64/xorg/modules/extensions/libglx.so
    # If it's tiny (~280 KB), repoint to NVIDIA (~14 MB):
    mv /usr/lib64/xorg/modules/extensions/libglx.so \
       /usr/lib64/xorg/modules/extensions/libglx.so.mesa
    ln -sf /usr/lib64/xorg/modules/extensions/libglx.so.390.30 \
          /usr/lib64/xorg/modules/extensions/libglx.so
  4. Start the headless X and allow local clients:
    /usr/bin/X :0 -noreset -nolisten tcp -logfile /var/log/Xorg.0.log & sleep 5
    DISPLAY=:0 xhost +LOCAL:

VirtualGL + TurboVNC usage

# One-time server config (answers: enable, allow users, etc.)
/opt/VirtualGL/bin/vglserver_config

# Start a viewer desktop (TurboVNC)
/opt/TurboVNC/bin/vncserver    # connect with a VNC viewer

# In the VNC terminal (bash)
export VGL_DISPLAY=:0
vglrun -d :0 glxinfo | egrep -i 'opengl vendor|renderer|version'
vglrun -d :0 glxgears

Expect: OpenGL vendor = NVIDIA Corporation; renderer = Tesla M2090/…; gears window smooth.

Start at boot (SysV init)

Append to /etc/rc.d/rc.local and ensure it’s executable:

cat >>/etc/rc.d/rc.local <<'EOBOOT'
# --- Headless Xorg for VirtualGL on :0 ---
if ! pgrep -f "X .*:0" >/dev/null 2>&1 ; then
  /usr/bin/X :0 -noreset -nolisten tcp -logfile /var/log/Xorg.0.log &
  sleep 5
  DISPLAY=:0 /usr/bin/xhost +LOCAL:
fi
# --- end ---
EOBOOT
chmod +x /etc/rc.d/rc.local

Troubleshooting

  • BadWindow (NV-GLX) ⇒ X on :0 is missing NVIDIA GLX. Recheck the libglx.so symlink and Load "glx" section; restart X and look for “NVIDIA GLX Module …” in /var/log/Xorg.0.log.
  • X_GLXCreateContext BadValue (plain glxgears) ⇒ you’re trying direct GLX into a forwarded display. Use vglrun -d :0 ... or LIBGL_ALWAYS_INDIRECT=1 glxgears.
  • Fonts warnings ⇒ install xorg-x11-fonts-* packages above.
  • csh users ⇒ use setenv VGL_DISPLAY :0 instead of export.

Note: On CentOS/RHEL 6 you cannot install VirtualGL 3.x or TurboVNC 3.x due to glibc and libXfont2 requirements. Stick to the versions shown here.

💡 Before you begin: If your CentOS 6 system no longer updates or gives certificate errors, follow this CentOS 6 Vault repo & yum certificate fix guide first to restore working repositories.

Popular posts from this blog

Meal Prepping: The Key to Diet Ease and Compliance for Healthy Weight Management

Balanced Bites: The Secret to Sustainable Weight Loss Through Macro and Micro Nutrients