2018年7月23日 星期一

在 docker 裡面跑 GUI 程式

一開始玩 docker 主要都是為了伺服器的應用 (例如 ethercalc ldap), 所以只需要文字介面。 最近玩 ML/DL/AI 程式, 經常需要顯示圖片。 每次都要在 docker 裡面用 AI 程式在分享的目錄裡產生圖片, 再從外面 (host) 用看圖軟體看, 有點囉嗦。 如果是影片, 就更麻煩了。 搜尋到這篇 Running GUI apps with Docker, 略微修改他的做法, 得到以下簡單步驟讓你可以在 docker 裡面執行圖形介面程式並直接顯示在 host 實體機的 X Window 環境。

我們拿 ubuntu 18.04 的官方 docker 及輕巧的 feh 看圖程式來做實驗。

  1. 查看你自己的 user name 跟 UID: echo $UID $USER 例如我看到 1000 ckhung。
  2. 啟動 docker: docker run -it --name xwin -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/ckhung/data:/tmp/exdata ubuntu:18.04 bash 這裡有兩個重點: (1) 把 host 裡的 DISPLAY 環境變數傳進 docker 裡面。 (2) 讓 docker 直接存取 host 的 /tmp/.X11-unix (裡面有一個 X11 在用的 socket)。 至於其他選項, 因為我們要進 bash, 所以要用 -it; 第二組 -v 則是為了分享一般的檔案。
  3. 進入 docker 之後, 安裝一個測試用的 GUI 軟體, 例如 apt update ; apt install feh
  4. 照外面的 $USER 跟 $UID, 在 docker 裡面也建立一個同名同代號的 user: useradd -m -s /bin/bash -u 1000 ckhung
  5. 變身成新的 user: su ckhung
  6. 如果你在 host 的 /home/ckhung/data 有放一些圖片, 那麼從 docker 裡下 feh /tmp/exdata 就可以看到這些圖片了! 在 feh 裡面, 按 q 或 ESC 離開。 其他按鍵請見 man feh。

實際上執行時, 我看到 X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 130 (MIT-SHM) Minor opcode of failed request: 3 (X_ShmPutImage) 之類的錯誤。 根據 這個 issue, 砍掉 docker, 重新啟動時加上 --ipc=host 選項, 才成功。 不過這是比較危險的方法, 只適用於你信任那個 docker 映像檔的情況, 所以我沒直接寫進上面 docker run ... 那一句。

安裝 vlc 播放影片也 ok, 只是沒有聲音。 又, 後來發現我要用的那個 docker 的 opencv 並沒有把 GUI 編譯進去, 所以還是沒辦法看影片。 沒關係, 已前進一小步, 今天先這樣就滿足了。

沒有留言:

張貼留言