---
# System prepended metadata

title: 安裝 VirtualGL

---

# DeepStream「Failed to create EGLImage」完整故障排除筆記（Docker + NoMachine + Jetson Orin）

> 適用：**Jetson Orin（JetPack 6.x）** / **DeepStream 7.1** / **Docker 容器** / **NoMachine 遠端桌面**；要在遠端**看到畫面**執行 `deepstream-test1` 等 sample。
>
> 若只做推論不看畫面，建議改走 **Headless（不開窗）**，更穩更省事（見第 6 章）。

---

## TL;DR（五行結論）

1. `nvbufsurface: Failed to create EGLImage` 幾乎一定是**容器內沒有可用的 EGL + 顯示**（NoMachine 的虛擬 X display 預設沒有硬體 EGL）。
2. DeepStream sample 預設用 `nveglglessink` 開窗，**必須**能建立 EGLContext/EGLImage，否則就炸。
3. 解法 A：**Headless** → 把 sink 改成 `fakesink`/`filesink`，完全不走 EGL。
4. 解法 B（本文主線）：要看畫面 → 用 **VirtualGL（EGL back end）**，讓 GPU 在伺服器端繪圖，畫面由 NoMachine 傳輸。
5. 關鍵點：`DISPLAY=:1`（NoMachine）、**xhost/Xauthority 授權**、容器掛載 `/dev/dri`、用 `vglrun -d egl`（或 `-d /dev/dri/card1`）。

---

## 1. 問題現象與成因

### 1.1 你可能看到的訊息

* `libEGL warning: DRI2 failed to authenticate`
* `nvbufsurface: Failed to create EGLImage`
* `Failed to set buffer pool to active`
* `Unknown or legacy key 'nvbuf-memory-type'`
* `/bin/bash: lsmod: command not found`, `/bin/bash: modprobe: command not found`

### 1.2 代表什麼？

* **EGL/顯示路徑問題（主因）**

  * NoMachine 會開自己的虛擬 X display（常見 `:1`），預設**沒有**直通硬體 EGL/DRI；容器內若直接用 `nveglglessink`，會在建立 `EGLImage` 時失敗。
  * `DRI2 failed to authenticate` 通常是 X 授權/DRI 權限或顯示環境不對。
* **非致命訊息（可忽略）**

  * `Unknown or legacy key 'nvbuf-memory-type'`：DeepStream 7.1 對舊 key 的提醒。
  * `lsmod/modprobe not found`：容器是精簡版，沒有 kmod；不影響 sample 執行。

> 一句話：**顯示/EGL 沒打通 → `EGLImage` 建立失敗 → `nvinfer` buffer pool 啟不動 → pipeline 掛**。

---

## 2. 解法地圖（挑一條）

* **A. Headless（不開窗）**：把 sink 改 `fakesink` 或 `filesink`，完全不走 EGL，最省心（見第 6 章）。
* **B. 有畫面（本文主線）**：NoMachine + **VirtualGL（EGL back end）**。

  * 主機（Jetson）裝 VirtualGL、設定 `vglusers` 與 `/dev/dri` 權限、放行 X 授權。
  * 容器裝 VirtualGL user-space，用 `vglrun` 包住 DeepStream。

> 下文以 **方法 B** 詳述；方法 A 請直接跳第 6 章。

---

## 3. 架構概念（方法 B：VirtualGL）

```
Client（你）  ⇐  NoMachine 傳輸視覺畫面  ⇐  VirtualGL 將 GPU 繪圖結果截取並送出
                                           ⇐  DeepStream 在 Docker 內用 EGL/GPU 繪圖
                                 Jetson Orin /dev/dri/card1 提供 EGL/GPU 能力
```

* 你連到 Jetson → NoMachine 啟一個 X Display `:1`（2D 桌面）。
* DeepStream 在容器內由 VirtualGL 代理 OpenGL/EGL 呼叫，用 **伺服器端 GPU** 繪圖，再把畫面回送到 `:1` 顯示。

---

## 4. 實作步驟（一步步照做）

> 以 **Jetson Orin + Ubuntu 22.04 + DeepStream 7.1 + NoMachine** 為例。

### 4.1 主機（Jetson）前置檢查

```bash
nvidia-smi                    # Jetson 會顯示 Orin (nvgpu)
echo $DISPLAY                 # 透過 NoMachine 通常是 :1
echo $XDG_SESSION_TYPE        # 多半是 tty 或 x11
ls -l /tmp/.X11-unix          # 常見 X1 / X1001 等 socket
```

### 4.2 主機安裝與設定 VirtualGL（EGL only）

> ARM64 上 apt 沒 `virtualgl`，用官方 .deb；設定時選「EGL back end only」。

```bash
# 安裝 VirtualGL (ARM64)
wget -O ~/virtualgl_3.1_arm64.deb \
  https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb
sudo dpkg -i ~/virtualgl_3.1_arm64.deb || \
  (sudo apt -f install -y && sudo dpkg -i ~/virtualgl_3.1_arm64.deb)

# 啟用伺服器設定（互動精靈）
sudo /opt/VirtualGL/bin/vglserver_config
# 在選單中選：3) Configure server for use with VirtualGL (EGL back end only)
# 問到下列選項時一律選 Enable/Yes：
# - 建立 vglusers、限制 /dev/dri 給 vglusers
# - 啟用安全設定 / Turbo

# 把登入帳號加入 vglusers 並生效
sudo usermod -aG vglusers $USER
newgrp vglusers

# 放行 X11 給容器內的 root（常見 DeepStream 以 root 跑）
DISPLAY=:1 xhost +local:root

# 找出可用 EGL 裝置（Jetson 常見是 /dev/dri/card1）
/opt/VirtualGL/bin/eglinfo -e
```

> **注意**：如果 `eglinfo -e` 顯示 `egl0 → /dev/dri/card1`，等下容器內建議用 `-d egl` 自動選或直接用 `-d /dev/dri/card1`。

### 4.3 啟動 Docker 容器（要看畫面）

```bash
docker run -it --rm --net=host --ipc=host \
  --gpus all \
  -e DISPLAY=:1 \
  -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video,graphics \
  -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
  --device=/dev/dri \
  --group-add video \
  --name ds71 \
  nvcr.io/nvidia/deepstream:7.1-triton-multiarch
```

**參數說明**

* `--gpus all`：新版 Docker 推薦寫法（相當於舊的 `--runtime=nvidia`）。
* `DISPLAY=:1`：明確把容器指到 NoMachine 的 X 顯示。
* `-v /tmp/.X11-unix`：把 X socket 映進容器。
* `--device=/dev/dri`：把 DRI 裝置帶進容器（EGL 需要）。
* `--ipc=host`：DeepStream/GStreamer 場景常用（共享 IPC）。

### 4.4 容器內安裝 VirtualGL（user-space）

```bash
apt-get update && apt-get install -y wget
wget -O /tmp/virtualgl_3.1_arm64.deb \
  https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb
dpkg -i /tmp/virtualgl_3.1_arm64.deb || \
  (apt-get -f install -y && dpkg -i /tmp/virtualgl_3.1_arm64.deb)
```

### 4.5 容器內視覺小測試（彩色球）

```bash
/opt/VirtualGL/bin/vglrun -d egl /opt/VirtualGL/bin/eglxspheres64 -f 240 -w 800x600
# 若不穩或裝置對不準，可強制用卡：
/opt/VirtualGL/bin/vglrun -d /dev/dri/card1 /opt/VirtualGL/bin/eglxspheres64 -f 240 -w 800x600
```

> 看得到小視窗 + 有 FPS ⇒ **EGL 路徑暢通**。

### 4.6 容器內執行 DeepStream Sample（test1）

```bash
cd /opt/nvidia/deepstream/deepstream-7.1/sources/apps/sample_apps/deepstream-test1
make   # 若尚未編譯出 deepstream-test1-app

# 自動選擇 EGL 裝置
/opt/VirtualGL/bin/vglrun -d egl ./deepstream-test1-app ./dstest1_config.yml
# 或強制指定
/opt/VirtualGL/bin/vglrun -d /dev/dri/card1 ./deepstream-test1-app ./dstest1_config.yml
```

---

## 5. 常見錯誤 → 對應手法

| 症狀/錯誤                                       | 可能原因                              | 處置                                                                   |
| ------------------------------------------- | --------------------------------- | -------------------------------------------------------------------- |
| `nvbufsurface: Failed to create EGLImage`   | 容器內沒有可用 EGL（NoMachine 虛擬 X 沒硬體加速） | 走 **VirtualGL（EGL）** 或改 **Headless**                                 |
| `DRI2 failed to authenticate`               | 缺 X 授權 / DRI 權限                   | 主機 `xhost +local:root` 或改掛 `$XAUTHORITY` 進容器                         |
| `invalid EGL device`                        | 指錯 DRI 裝置                         | `eglinfo -e` 找正確 `/dev/dri/cardX`；用 `-d /dev/dri/card1`              |
| 有視窗但黑畫面                                     | NoMachine 端未啟用硬體加速/合成             | 到 NoMachine Server 設定啟用「Use acceleration for display processing」或類似項 |
| `Unknown or legacy key 'nvbuf-memory-type'` | 參數舊名                              | 通常可忽略；必要時對照 DS 7.1 新鍵名                                               |
| `lsmod/modprobe not found`                  | 容器精簡                              | 可忽略                                                                  |
| `DISPLAY=:0` 仍不行                            | 機器沒有實體 Xorg/螢幕                    | 遠端情境請用 `:1` + VirtualGL；本地螢幕才用 `:0`                                  |

---

## 6. \*\*Headless（不開窗）\*\*作法（最穩定）

### 6.1 用 `deepstream-app` 的 config

```ini
[sink0]
enable=1
type=5        # fakesink（不顯示）
sync=0
```

Docker 指令也更簡單（不用掛 X 與 DISPLAY）：

```bash
docker run -it --rm --net=host --ipc=host \
  --gpus all \
  -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video \
  --device=/dev/dri \
  nvcr.io/nvidia/deepstream:7.1-triton-multiarch \
  deepstream-app -c /path/to/your_config.txt
```

### 6.2 若要沿用 test1 程式

* 把 pipeline 的末端 `nveglglessink` 換成 `fakesink`/`filesink`（需改 sample 或其 YAML/INI）。
* 核心 idea：**不經過 EGL**，就不會有 `EGLImage` 問題。

---

## 7. 安全與維運注意

* `xhost +local:root` 只允許本機 root 連入 X，簡單但安全性一般。要更嚴格可改用 **Xauthority cookie**：

  * Docker 加：`-v $XAUTHORITY:/root/.Xauthority:ro -e XAUTHORITY=/root/.Xauthority`
  * 確保 `DISPLAY` 與 `/tmp/.X11-unix` 相符。
* Jetson/驅動更新後，`/dev/dri` 權限可能被重置；出問題重跑：

  * `sudo /opt/VirtualGL/bin/vglserver_config -config +s +f -t -egl`
* 版本相容性：DeepStream 7.1 / JetPack 6.x / 驅動（如 535/540+）需互相匹配，混裝常見各式 EGL 問題。
* 效能：`vglrun` 可調整壓縮品質（`-q`）、幀率限制（`-fps`）等；若追求低延遲/高畫質，可考慮 **TurboVNC + VirtualGL** 搭配。

---

## 8. 快速指令卡（可直接貼到 README）

```bash
# Host（Jetson）
wget -O ~/virtualgl_3.1_arm64.deb https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb
sudo dpkg -i ~/virtualgl_3.1_arm64.deb || (sudo apt -f install -y && sudo dpkg -i ~/virtualgl_3.1_arm64.deb)
sudo /opt/VirtualGL/bin/vglserver_config      # 選 3) EGL only，選項全 Yes
sudo usermod -aG vglusers $USER && newgrp vglusers
DISPLAY=:1 xhost +local:root
/opt/VirtualGL/bin/eglinfo -e                 # 確認 card1/egl0

# Docker（要顯示畫面）
docker run -it --rm --net=host --ipc=host --gpus all \
  -e DISPLAY=:1 -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video,graphics \
  -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
  --device=/dev/dri --group-add video \
  --name ds71 nvcr.io/nvidia/deepstream:7.1-triton-multiarch

# Container 內（裝 VGL + 驗證 + 跑 DeepStream）
apt-get update && apt-get install -y wget
wget -O /tmp/virtualgl_3.1_arm64.deb https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb
dpkg -i /tmp/virtualgl_3.1_arm64.deb || (apt-get -f install -y && dpkg -i /tmp/virtualgl_3.1_arm64.deb)
/opt/VirtualGL/bin/vglrun -d egl /opt/VirtualGL/bin/eglxspheres64 -f 240 -w 800x600

cd /opt/nvidia/deepstream/deepstream-7.1/sources/apps/sample_apps/deepstream-test1
make
/opt/VirtualGL/bin/vglrun -d egl ./deepstream-test1-app ./dstest1_config.yml
# 或：/opt/VirtualGL/bin/vglrun -d /dev/dri/card1 ./deepstream-test1-app ./dstest1_config.yml
```

---

## 9. 快速決策樹（遇到同類問題時）

1. **需要視窗嗎？**

   * 不需要 → **Headless**（改 `fakesink`/`filesink`） → Done。
   * 需要 → 2。
2. **遠端（NoMachine/VNC）或本機螢幕？**

   * 本機實體螢幕 → `DISPLAY=:0` + X 授權；通常可用。
   * 遠端 NoMachine → **VirtualGL（EGL）** 路線（本文）。
3. **還是報 `EGLImage` 失敗？**

   * 檢查 `xhost +local:root`、容器是否有 `/dev/dri`、`vglrun -d egl eglxspheres64` 能跑。
   * 不穩就強制 `-d /dev/dri/card1`。
   * 仍不行 → 先走 **Headless** 完成工作，再回頭查 NoMachine/驅動/權限。

---

### 備註

* 本筆記以 Jetson Orin/Ubuntu 22.04/DeepStream 7.1/NoMachine 為範例實測；x86\_64 環境僅需更換對應架構的 VirtualGL 套件。
