KNOWLEDGE - COLUMN ナレッジ - コラム

DockerからGUIを使ってみよう

col229_main

先端技術部
テクニカルスペシャリスト 黒住 好忠 黒住さん顔写真_184x297

こんにちは。テクニカルスペシャリストの黒住です。

これまで「Windows 10 + WSL + Windows版のDocker Desktop」というコンテナ環境を多用していましたが、Windows 11が登場してから「Windows 11 + WSL + WSL上のdocker-ce + nvidia-docker2」という環境に移行しました。

そして、WSL上のDockerを使う上で悩みの種だった「OpenCVなどのGUI画面を表示できない」という課題も、Windows 11から解消されました。そこで今回は、「WSL上で動かしているDockerコンテナからGUI画面を表示する方法」についてご紹介しようと思います。

WSL上のDockerコンテナからGUI表示

Windows 11 build 22000以降、WSLg(Windows Subsystem for Linux GUI)という機能を使って、「WSL上でGUIアプリケーションを実行」できるようになりました。

公開されているWSLgに関する情報は、「WSL上でLinuxのGUIアプリケーションを動かす方法」に関する内容が多いのですが、実は「WSL上のDockerコンテナで動いているアプリケーションでもGUI表示が可能」になります。(WSL上のアプリではなく、WSL上のDockerコンテナで動いているアプリという点がポイント)

つまり、WSLgを使えば、今までは実現できなかった「WSL上で動くDockerコンテナから、OpenCVなどを使ったGUI画面の表示」が簡単に実現できるのです。

早速、DockerコンテナからWSLgを使ってGUIを表示する方法を見ていきましょう。

docker composeの設定

Windows 11でWSLが最新の状態になっていれば、Docker側の設定に「WSLgと連携できるような定義を追加」すると、Docker側からWSLgが利用できるようになります。

以下に、具体的なdocker-compose.yml の設定例を示します。

version: "3.9"
services:
  py3:
    build:
      context: ./py3
      dockerfile: Dockerfile
    working_dir: /workspace
    entrypoint: ["python", "app.py"]
    volumes:
      # Workspace
      - ./workspace:/workspace
      # WSLg
      - /tmp/.X11-unix:/tmp/.X11-unix
      - /mnt/wslg:/mnt/wslg
    environment:
      # WSLg
      - DISPLAY=$DISPLAY
      - WAYLAND_DISPLAY=$WAYLAND_DISPLAY
      - XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
      - PULSE_SERVER=$PULSE_SERVER
      # GPUを使うための設定
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all
    # GPUを使うための設定
    deploy:
      resources:
        reservations:
          devices:
            - capabilities:
              - gpu

WSLgとは関係のない部分も含まれていますが、ポイントは volumesenvironment に「# WSLg」というコメント付きで記載している部分になります。

volumes で、 /tmp/.X11-unix/mnt/wslg のマッピングを行い、environment で、 DISPLAY , WAYLAND_DISPLAY , XDG_RUNTIME_DIR , PULSE_SERVER という環境変数の定義を行います。

なお、上記サンプルでは「docker compose」を前提としていますが、同様のマッピングと環境変数の設定を行えば、Docker単独でもWSLgの利用が可能だと思われます。

この状態で、例えば以下のようなOpenCVを使ったPythonコードを実行すれば、「Windows側にOpenCVのGUI画面が表示」されます。また、GUI画面の表示だけでなく、画面に対するマウスやキーボードの操作なども通常通り行うことができます。(WSLgが登場した当初は、2回目以降の起動時に前回押していたキーが押されたままの状態になる不具合が存在していましたが、現在はこの問題は解消されています)

import cv2TITLE = "docker on WSL2"cv2.namedWindow(TITLE, cv2.WINDOW_AUTOSIZE)# 画像表示img = cv2.imread("fireworks.jpg")cv2.imshow(TITLE, img)print("ESCキーを押せば終了")while True:if cv2.waitKey(1) == 0x1B:breakcv2.destroyAllWindows()


Windows側に表示されたGUI画面
図:Windows側に表示されたGUI画面(処理自体はWSL上のDockerコンテナで動かしている)

上記の docker-compose.ymlapp.py を含むサンプルコード一式は、以下のGitHubリポジトリで公開しているので、必要に応じて参照してみてください。
(※外部リンク)GitHubリポジトリ

最後に

今回は、「WSL上のDockerコンテナからGUI画面を表示する方法」について取り上げてみました。

紹介したサンプルは「GUI画面を表示するPythonコードの実行」という内容でしたが、Dockerコンテナ上で実行しているJupyterLabなどに「ブラウザ経由で接続している場合でも、WSLgは利用可能」です。

また、今回は取り上げていませんが、Windows 11では「WSLの初回起動時にdockerサービスを自動で起動」させたり、「WSL上からWebカメラなどのUSBデバイスをUSBIP経由で利用」することも可能なので、色々試してみてくださいね。

※ただしUVCデバイスを/dev/video*として認識させるためにはカーネルのビルドが必要になります。

開発環境についても、JupyterLabなどを利用する方法以外に、VSCodeからRemote-Containersという拡張機能を利用して、直接WSL上のDockerにアタッチした状態での開発も可能なので、目的や用途に合わせて使い分けてみてください。

それでは、また次回のコラムでお会いしましょう。

参考リンク

記事に関連する参考リンクです。(※いずれも外部リンク)

当サイトの内容、テキスト、画像等の転載・転記・使用する場合は問い合わせよりご連絡下さい。

エバンジェリストによるコラムやIDグループからのお知らせなどを
メルマガでお届けしています。

メルマガ登録ボタン


黒住 好忠

株式会社インフォメーション・ディベロプメント フェロー

この執筆者の記事一覧

関連するナレッジ・コラム

ITエンジニアの現地作業 ミスを減らす!作業本番のポイントとは

NTTのIP網移行と、通信の未来とは

ITエンジニアの現地作業 ミスを減らす!事前準備のポイントとは