dockerコンテナ内で動作するGUIの画面を他のコンテナで表示する方法
ほとんど需要ないと思いますが…。
xserverが動作しているコンテナ(コンテナA)に、GUIソフトが動作するコンテナ(コンテナB)を接続して、コンテナB上のGUIウィンドウをコンテナA上に転送します。
方法
まず、以下の2つを用意します。
今回は、コンテナAはuphy/ubuntu-desktop-jp
を、コンテナBは gns3/xeyes
を使います。
https://hub.docker.com/r/gns3/xeyes
https://hub.docker.com/r/uphy/ubuntu-desktop-jp
まず、コンテナAを起動します。
sudo docker container run -it --rm --name container-a -p 8080:8080 -v /tmp/.X11-unix uphy/ubuntu-desktop-jp:latest
uphy/ubuntu-desktop-jp
では、 http://localhost:8080/
に接続することでnoVNC経由で画面が表示できます。 確認しておきましょう。
次に、コンテナBを起動します。
sudo docker container run -it --rm --name container-b -e DISPLAY=:0.0 --volumes-from container-a gns3/xeyes
うまくいっていれば、コンテナAの画面(http://localhost:8080/)に、カーソルを追いかける目玉が表示されているはずです。
仕組み
ミソは2つあります。
1つめのミソは、/tmp/.X11-unix
のコンテナ間での共有です。
/tmp/.X11-unix
は、xserverとxclientの間の unix domain socketです。要はこのソケットを通じて、GUIを表示したいソフト(xclient)とその処理をするxserverとの間で情報をやりとりしています。
今回は、コンテナA内の /tmp/.X11-unix
を、dockerのData Volume機能を使ってコンテナBに共有することで、あたかもコンテナBがxserverを起動しているかのような状態にしています。
2つめのミソは、環境変数DISPLAYの定義です。
コンテナB起動時の -e DISPLAY=:0.0
がそれです。
DISPLAYはxserverのパスを指定するための環境変数ですが、今回はコンテナBにコンテナAの/tmp/.X11-unix
をマウントしているので、ローカルに画面があるときと同じ:0.0
としています。