詳解Docker容器運行GUI程序的方法

華爲雲開發者聯盟 發佈 2024-04-10T21:39:28.538297+00:00

本文分享自華為雲社區《Docker容器運行GUI程序的方法(直接進入Docker容器運行或通過SSH連接Docker容器運行)》,作者:MAVER1CK 。原文詳情:https://bbs.huaweicloud.com/blogs/393738?

本文分享自華為雲社區《docker容器運行GUI程序的方法(直接進入Docker容器運行或通過SSH連接Docker容器運行)》,作者:MAVER1CK 。原文詳情:https://bbs.huaweicloud.com/blogs/393738?utm_source=jinritoutiao&utm_medium=bbs-ex&utm_campaign=other&utm_content=content

以下兩種方法都需要先在主機執行 xhost + 命令,若無該命令,先apt安裝 x11-xserver-utils 後再執行,否則會報 No protocol specified 這個錯

sudo apt install x11-xserver-utils
xhost +

直接進入Docker容器運行

針對遠程容器

docker-compose.yml中需要綁定掛載 /tmp/.X11-unix

    volumes:
      - "/tmp/.X11-unix:/tmp/.X11-unix:rw"
    environment:
      - DISPLAY=$DISPLAY
      - QT_X11_NO_MITSHM=1

若出現 X11 connection rejected because of wrong authentication. 這個錯,則需要再掛載 ~/.Xauthority

    volumes:
      - "/tmp/.X11-unix:/tmp/.X11-unix:rw"
      - "~/.Xauthority:/root/.Xauthority:rw"
    environment:
      - DISPLAY=$DISPLAY
      - QT_X11_NO_MITSHM=1

這種方法有個問題:雖然將主機中的Xauthority文件使用綁定掛載共享到容器中,但容器中的該文件數據更新不及時(可以在主機和容器中分別使用 xauth list 命令查看詳情,對比這兩個文件的內容),導致即使掛載Xauthority,也會報 X11 connection rejected because of wrong authentication. 這個錯,必須重啟容器才可以繼續顯示圖像。而通過SSH連接容器則不會出現這個問題。
舉個例子:

  1. 一台NUC上運行了一個容器,已經使用docker compose up -d 部署了容器,在開機腳本里寫了自啟容器的命令,每次NUC開機都會自動啟動容器
  2. 使用筆記本電腦ssh連接到了NUC,再在這個ssh連接中進入容器
  3. 在容器中運行GUI程序,成功顯示了窗口
  4. 退出容器,並斷開了與NUC的ssh連接
  5. 再次ssh連接NUC,重複步驟2. 3.,但未能顯示圖形,報錯:X11 connection rejected because of wrong authentication.
  6. 在容器中執行 xauth list 命令,再在NUC中執行相同命令,可以看到設備名相同,但cookie值不同,導致認證失敗
  7. 不斷開ssh連接,重啟容器並再次運行GUI程序,成功顯示圖形

針對本地容器

直接使用docker exec命令或通過下文ssh的方法進入容器

例如容器中使用的是bash

docker exec -it [容器名稱] bash

然後在當前終端中輸入命令執行GUI程序即可

通過SSH連接Docker容器運行

根據官方文檔說明,在 host 網絡模式下無法使用埠映射,為了使容器的ssh埠和主機的ssh埠不衝突(做到既可以連接主機,又可以連接容器),需要修改容器中默認的ssh埠,又因為容器中默認為root用戶,且為隨機生成密碼,所以還要修改容器的ssh配置文件,允許以root身份ssh登陸,並修改容器root用戶的密碼,最後還要讓容器每次啟動的時候自動啟動ssh服務(因為容器沒有systemd,不會自啟ssh服務)。注意不能掛載主機的Xauthority文件,但要掛載 /tmp/.X11-unix

volumes:
      - "/tmp/.X11-unix:/tmp/.X11-unix:rw"
environment:
      - DISPLAY=$DISPLAY
      - QT_X11_NO_MITSHM=1

1. 修改容器ssh埠並允許root用戶登陸

vim /etc/ssh/sshd_config
  • 將 Port 解注釋,並把值從22改為其他值(不能使用主機正在使用的埠,因為容器在 host 模式下與主機共用埠),比如2222
  • 然後找到 PermitRootLogin ,解注釋並把值改為 yes

2. 修改docker-compose.yml,使容器啟動時自啟ssh服務:在 command 處增加命令

service ssh start

因為我的容器已經在啟動時執行了 tail -f /dev/null 命令,因此需要下面這種寫法以使容器執行多條命令

    command: bash -c "service ssh start && tail -f /dev/null"

3. 最後通過ssh命令連接

ssh -p 2222 root@localhost -Y

關注,第一時間了解華為雲新鮮技術~

關鍵字: