結論
devcontainerを使うのが一番楽.それ以外であれば,GUIアプリ起動時のエラーError: Can't open display: :0
を回避するためにDISPLAY=<ホストのDISPLAY>
として合わせるのがいい.ただしホストがWindowsだとDISPLAY=host.docker.internal:<ホストのDISPLAY変数>
とする必要がある.
devcontainerの場合はDISPLAY環境変数や/tmp/.X11-unixのマウントなどはすべてdevcontainerがやってくれるので本記事の手順は不要です.ソースなどはこちらに書いたので飛んで参照してください.
環境
- Ubuntu 20.04.6 LTS, Docker 28.0.1
- Windows 11 Pro(24H2), Docker Desktop 4.36.0
DISPLAY=:0とすると起こること
たとえばGUIアプリケーションのxeyesを起動しようとすると,
$ xeyes
Error: Can't open display: :0
とエラーになる.
対処法(Windowsホスト)
前提として,以下のサイトのようにVcXsrvの設定と起動までを済ませておきます.
自分の環境では,この状態でコンテナ内のDISPLAY=:0
だと上述のエラーを吐きました.
理由は,Windowsホストの場合は,DISPLAY変数に:0
だけでなくホストのIPも指定してやる必要があるからです.なので,コンテナ内のDISPLAY
環境変数を:0
ではなくhost.docker.internal:0
と設定します1.
なお,VcXsrvで設定したディスプレイ番号とDISPLAY
変数に設定したディスプレイ番号が異なる場合もエラーになります.VcXsrvの設定のdisplay numberを-1にするとVcXsrvが自動でディスプレイ番号を決定しますが,今回の場合はDISPLAY環境変数と一致しないと困るのでVcXsrvの設定で0に固定しておくとよいです.
対処法(Ubuntuホスト)
Ubuntuホストでコンテナ内のDISPLAY
環境変数を:0
にした場合も上述のエラーが出ました.これは,自分の環境ではホストのディスプレイ番号とコンテナ内のDISPLAY
環境変数の不一致が原因でした.
実際,ホスト上でwho
コマンドを打ってディスプレイ番号を確認すると,
$ who
hoge :1 2025-03-18 09:16 (:1)
のようになったため,ディスプレイ番号は:1
とわかります.
したがってこの場合は,コンテナ内でDISPLAY=:1
と設定すると正常に動作します.
その他参考サイト
-
host.docker.internal
はホストのIPアドレスを指す特別な名前です.ただし,Desktop版のDockerでしか動作しないので注意が必要です.https://docs.docker.jp/desktop/networking.html#desktop-networking-i-want-to-connect-from-a-container-to-a-service-on-the-host ↩