【WSL 2】dockerコンテナでGUIアプリを実行してWindowsで表示させたい
はじめに
GUIのアプリを開発してdockerコンテナ内で実行し、ホストのWindowsで表示したいと思いました。軽くやり方を調べたところ、WSL、Xサーバーなど色々な用語が出てきて混乱してしまったので自分なりにまとめてみました。
環境
この記事は以下の環境で検証しています。
- Windows 10 Pro 22H2(ビルド:19045)
- Rancher Desktop 1.14.1
- Docker version 26.1.0-rd, build cca8e72
- WSL バージョン: 2.2.4.0
WSLとは?
WSLはWindows Subsystem for Linuxの略で、Windows上でLinuxを動かすための分離された環境です。WSLを使うことでWindowsに複数のLinuxディストリビューション(Ubuntuなど)をインストールでき、それぞれのLinuxに入ってコマンドを実行したりできるようになります。WSLという環境の中に、独立した複数のLinuxが存在できるというイメージです。
WSLを使用するためにはインストールが必要ですが、コマンドを1行実行するだけという非常に簡単な手順となっています。
WSL 2とは?
WSLにはバージョンがあり、WSL 1とWSL 2があります。機能の違いについては以下ドキュメントを参照してください。
GUIアプリの実行という観点では、WSL 2ではLinux GUIアプリ実行をサポートする機能がプレビューで使えるようになりました。WSL 1では、GUI アプリを実行するには「VcXsrv」などのXサーバーソフトウェアをインストールする必要がありましたが、WSL 2のLinux GUIアプリサポートを使えば、何もしなくてもGUIアプリが実行できます。
ただし、Linux GUIアプリサポートが使えるのは以下のいずれかのWindows環境になります。
- Windows 10 ビルド 19044 以降
- Windows 11
WSLでの操作
WSLでの操作をいくつか確認してみます。ここでの操作はPowerShell(管理者モード)で実行しています。
インストールされているディストリビューションの確認
WSLでは複数のLinuxディストリビューションが存在できるということで、現在何が入っているのかを確認します。
PS C:\windows\system32> wsl --list --verbose
現在私のWindowsには以下の2つのLinuxディストリビューションが存在しているようです。
※WSLのインストールをした場合は、おそらくUbuntuがインストールされていると思われます。
NAME STATE VERSION
* rancher-desktop-data Running 2
rancher-desktop Running 2
デフォルトのディストリビューションに入る
デフォルトのディストリビューションにアクセスするには以下のコマンドを実行します。
PS C:\windows\system32> wsl
このようにプロンプトが変わり、Linuxに入ったことがわかります。ちなみに、これはPowerShellでのカレントディレクトリをLinuxから見たときのパスです。
/mnt/c/windows/system32 #
ここで通常のLinuxコマンドが実行できます。
※ただしディストリビューションによっては通常のLinuxコマンドが使えない場合があります。例えば上記のrancher-desktop-data
ではsudo
やls
などのコマンドが使えませんでした。
ディストリビューションを指定して入る
-d
オプションでディストリビューションを指定することでその環境にアクセスすることができます。
PS C:\windows\system32> wsl -d rancher-desktop
デフォルトのディストリビューションを変更する
-s
オプションで名前を指定することでデフォルトを変更することができます。よく使うディストリビューションに設定しておけばwsl
だけでアクセスできるので便利です。
PS C:\windows\system32> wsl -s rancher-desktop
WSL上のGUIアプリをWindowsで表示する
ではいよいよGUIアプリの実行を試してみます。
ただし、ここではdockerコンテナ内でGUIアプリを実行するのではなく、まずはWSL上にあるLinuxでGUIアプリを実行し、ホストであるWindowsに表示させてみます。
まずはwsl
コマンドを使って目的のLinuxに入ります。
GUIアプリをインストールしますが、まずはインストールするコマンドを調べる必要があります。Ubuntuなどであれば問題ないですが、ベースとなるディストリビューションが分からない場合は以下のように調べます。
# cd /etc
# ls
alpine-release ethertypes localtime(以下略)
〇〇-releaseから、Alpineであることがわかりました。よって、apk
コマンドを使います。
※Ubuntuであれば公式サイトにあるコマンドが使えます。
xclockのインストールと確認
簡単なGUIアプリということで、xclockをインストールして確認してみます。
# sudo apk add xclock
実行します。
# xclock
Linux上で実行されたGUIアプリをWindowsで表示することができました。
dockerコンテナ内のGUIアプリをWindowsで表示する
ここからがこの記事でやりたかったことです。
Windowsでアプリの開発を行う⇒dockerイメージをビルドする⇒dockerコンテナでアプリを起動する⇒Windowsで表示する
という流れになります。
検証用ファイルの用意
検証用GUIアプリはPythonでturtleのScreenを表示するだけのものです。
from turtle import Screen
screen = Screen()
screen.setup(width=600, height=600)
screen.exitonclick()
Dockerfileです。
FROM python:3
WORKDIR /usr/src
docker-compose.ymlです。
version: "3.9"
services:
app:
build:
dockerfile: ./Dockerfile
volumes:
- ./src:/usr/src
# WSL
- /tmp/.X11-unix:/tmp/.X11-unix
- /mnt/wslg:/mnt/wslg
tty: true
environment:
#- DISPLAY=:0
#- WAYLAND_DISPLAY=wayland-0
#- XDG_RUNTIME_DIR=/mnt/wslg/runtime-dir
#- PULSE_SERVER=unix:/mnt/wslg/PulseServer
- DISPLAY=$DISPLAY
- WAYLAND_DISPLAY=$WAYLAND_DISPLAY
- XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR
- PULSE_SERVER=$PULSE_SERVER
ここでは、コンテナ内のGUIアプリとWIndowsが通信できるようにするために、以下2つの設定を行います。
- 特定のディレクトリのマウント(WSLというコメントがある2行です)
- 環境変数を設定(4行)
前述のとおり、WSL 2のGUIサポートの機能を使っていれば、ホストのWindows側にはXサーバーなどをインストールする必要はなく、環境変数$DISPLAY
などもWSL環境に既に設定されている状態となります。そのため、LinuxでGUIアプリを実行するとWindowsに表示されました。
コンテナで同じようにするためには、コンテナにも同じ環境変数を設定する必要があるので、ここで設定しています。
ただし、WindowsからはWSL内の環境変数は直接取得できません。もしdocker-compose
コマンドをWindowsのまま(wsl
コマンドでLinuxに入らない)実行するのであれば、$DISPLAY
などには何も値が入っていないので、一度Linuxに入って環境変数を調べて直接設定するなどします。
wsl
コマンドでLinuxに入ってからdocker-compose
コマンドを実行すれば、$DISPLAY
などの表記で大丈夫です。
実行
以下コマンドを順に実行していきます。
$ wsl
# docker-compose up -d
# docker ps
CONTAINER ID IMAGE COMMAND CREATED
651b09a9969c python-docker-gui-app "python3" 5 seconds ag
# docker exec -it 651 /bin/bash
# python main.py
dockerコンテナで動いているturtleの画面をWindowsで表示することができました。
おわりに
今までWSLについてあやふやな理解だったのがだいぶ深められて良かったです。プレビューですがWSL 2のGUIサポートが非常に便利で驚きました。
この記事がどなたかの参考になれば幸いです。