Docker初心者がコンテナ内からGUIアプリケーション表示する方法に挑戦


表記の通り`Docker`の使い方について勉強をしているところです。`Docker`は手軽に環境を構築できて便利ですね。欲を言うとGUIアプリをもっと気軽に検証できれば最高だと思います。

実際には、コンテナ作成時に環境変数などを定義することでGUI表示にも対応可能なようですが、長めのオプションを書き込まないといけなかったりと、初心者にはちょっと気が重いです。なので`VSCode`を使ってもっと手軽にGUIアプリ表示を実現できないか検討してみました。

本手法は`WSL2`を利用しています。手順が若干トリッキーなのですが、一旦環境を構築すると、`WSL`で構築したLinuxディストリビューションのような感覚でGUIアプリを表示できました。自分のための備忘録として投稿致します。


:::note alert
注意事項
ここに記載しているGUIの表示手順は、WSLgを用いた正規の手法では無いと思います。予期しない不具合などが併発する可能性もありますので、自己責任で実施を検討してください。
:::





## １．実行環境
Windows 10 Pro (22H2)

以下が導入済みであること
- Docker Desktop
- WSL2

検証時の`WSL2`のバージョン

```powershell
PS C:\Users\hoge> wsl --version
WSL バージョン: 2.0.14.0
カーネル バージョン: 5.15.133.1-1
WSLg バージョン: 1.0.59
MSRDC バージョン: 1.2.4677
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.19045.3803
```


### １．１　WSL - Linux ディストリビューションの導入と動作確認
まずは`Microsoft Store`などから、通常通りLinuxディストリビューションを導入して、GUIアプリの表示が可能か動作確認を行います。

![ubuntuimage_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/3acabd4e-3e26-7fa8-ce1d-9d373a752cb1.jpeg)

ここでは`Ubuntu-22.04`を導入した前提で進めます。

導入した`Ubuntu-22.04`内に入り、下記のコマンドを実行し、GUIアプリがWindowsのデスクトップ上に表示されることを確認してください。

* x11-appsはxeyesとかxclockなどの簡単なXアプリのセット

```bash:
sudo apt update && sudu apt upgrade -y
sudo apt install x11-apps
xeyes
```


問題がなければ以下のように👀が表示されます。

![ubuntu_eyes.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/e307d5c5-84aa-f849-798d-70e93534809b.jpeg)

確認が終わったら、全部閉じてしまって構いません。
（`sudo apt remove x11-apps`しても良いです）

### １．２　既定のディストリビューションの変更

次に、Windows上の`Docker Desktop`を起動した状態で、`PowerShell`などを使って`wsl -l -v`と入力し、`WSL`ディストリビューションの状態を確認します。
下記のように`docker-desktop`の左側に`*`がある場合は、既定のディストリビューションが`Docker Desktop`になっているので、変更する必要があります。

```powershell
PS C:\Users\hoge> wsl -l -v
  NAME                   STATE           VERSION
* docker-desktop         Running         2
  docker-desktop-data    Running         2
  Ubuntu-22.04           Running         2
```

`Ubuntu-22.04`に変更するために`wsl -s Ubuntu-22.04`と入力します。

```powershell
PS C:\Users\hoge> wsl -s Ubuntu-22.04
この操作を正しく終了しました。
```

その後、もう一度`wsl -l -v`で確認してみます。

```powershell
PS C:\Users\hoge> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-22.04           Running         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2
```

既定のディストリビューションが`Ubuntu-22.04`になりました。

こうしておくことで、Dockerコンテナ内で起動したGUIアプリを`Rmote Desktop`が拾って、Windowusデスクトップに表示してくれるようになるみたいです。

:::note warn
この仕組みが良く理解できていません。今後、仕様の変更などで無効な手順になる可能性もあると思います。その際はご了承ください。
:::

![wsl-l.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/9d17b202-3f4b-9e55-0c06-3387b7c330bb.jpeg)

以上で事前環境の準備は完了です。



## ２．VSCodeによるDocke環境の構築

Windows上の`VSCode`を使ってGUIアプリ動作検証用のDockerイメージを作ります。

`VSCode`に以下のextensionを導入している前提で進めます。

- Dev Containers
- Docker
- WSL (←これは不要かも？)

![vc_extention.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/e2824b28-8860-71c6-8216-b2b463d1f05b.jpeg)



### ２．１　ファイルの構成

使用するファイルの構成は以下の通りです。Windowsの任意のフォルダに以下のファイルを格納し、`VSCode`でそのフォルダを開いてください。

┣━workspace/
┃　　┗━test.txt
┣━Dockerfile
┗━docker-compose.yml



```plaintext:workspace/test.txt
Hello!
```

```Dockerfile:Dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install -y x11-apps

# ディレクトリがない場合は自動で作成される
WORKDIR /workspace
```

```Dockerfile:docker-compose.yml
version: '3'
services:
  # サービス名
  xeyetes:
    # カレントディレクトリでイメージを構築
    build: .
    # データを永続化
    volumes:
      - ./workspace:/workspace
    # プロセスを継続させてコンテナの正常終了を防ぐ
    stdin_open: true
```

- 「stdin_open: true」が無いと直ぐにコンテナが閉じてしまってテストできない


### ２．２　コンテナの作成と起動

`VSCode`上で`docker-compose.yml`を右クリックし、`Compose Up`を選択。

![vsc_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/9ae464ab-d34c-2270-4e8f-bcd79b506476.jpeg)

その後、左サイドバーのDockerアイコンをクリックし、対象となるコンテナを選んで右クリック、`Attach Visual Studio Code`を選ぶ。

![vsc_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/b01f0e0a-3947-379a-9998-d88fd551133a.jpeg)

すると、新規の`VSCode`のウィンドウが立ち上がり、その`VSCode`ウィンドウを介してコンテナ内の操作が可能となる。

新規に立ち上がった`VSCode`でターミナルを立ち上げ`xeyes`コマンドを実行する。
上手く設定できていれば👀に再会できると思います。

![vsc_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/f2d6d51a-c35b-31a1-a663-ba8b5dbab7f5.jpeg)

このGUIアプリですが、`Remote Desktop`が表示しているみたいです。`WSL`のLinux ディストリビューション由来と思って拾っているのでしょうか？
この辺の挙動を理解できていない点が危うい気がします。。。

![vsc_04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/47863274-4f4f-2393-dc78-fc5bd28830ce.jpeg)


### ２．３　補足事項

#### Windowsの設定

不要かもしれませんが、検証時の「Windowsの機能の有効化または無効化」の状態も載せておきます


![kino.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/8adb077f-4834-e808-7886-313da5affe5b.jpeg)




#### Tips

今回の内容と直接関係ありませんが、この方法で`VSCode`経由で開発すると、volumeで永続化されたファイルに関しては、コンテナ内で編集した内容が、元ファイルにもリアルタイムに反映されてちょっと感動しました。（よく考えれば当たり前の挙動かもしれませんが）


![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/1e03d270-5628-aee9-f00f-4a1ee34a9bc1.jpeg)


## ３．Docker経由でopencvをGUI表示

別の例としてOpenCV画面をQT5で表示させてみたいと思います。
以下のHPを参考にさせて頂きました。

https://www.idnet.co.jp/column/page_229.html


### ３．１　ファイルの構成

ローカルファイルの構成

┣━py3/
┃　　┗━Dockerfile
┣━workspace/
┃　　┣━app.py
┃　　┗━lena_san.jpg
┗━docker-compose.yml

- `lena_san.jpg`は任意の画像です。ファイル名を変えた場合は`app.py`に記載したファイル名も変える必要があります。



```Dockerfile:py3/Dockerfile
FROM python:3.10.6-buster

ARG DEBIAN_FRONTEND=noninteractive

RUN apt update && apt install -y \
    libgl1-mesa-dev \
&&  apt clean \
&&  rm -rf /var/lib/apt/lists/*

RUN python3 -m pip install --upgrade pip \
&&  pip install --no-cache-dir \
    numpy \
    opencv-python

```


```python:workspace/app.py
import cv2

TITLE = "gui show test"
cv2.namedWindow(TITLE, cv2.WINDOW_AUTOSIZE)

img = cv2.imread("lena_san.jpg")
cv2.imshow(TITLE, img)

print("Press Esc key to close ...")
while True:
    if cv2.waitKey(1) == 0x1B:
        break

cv2.destroyAllWindows()
```


```Dockerfile:docker-compose.yml
version: "3.9" 
services:
  py3:
    build:
      context: ./py3
      dockerfile: Dockerfile
    volumes:
      - ./workspace:/workspace
    # プロセスを継続させてコンテナの正常終了を防ぐ
    stdin_open: true
```

### ３．２　コンテナの作成と起動

２章「VSCodeによるDocke環境の構築」と同じように`VSCode`経由でコンテナ内にアクセス、ターミナルで`/workspace`において`python app.py`を実行すると以下のように画像が表示されます。


![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264410/ff5d3a32-cf6d-cc5e-9178-6bcdbfea8994.jpeg)






## ４．参考

何度やっても`Error: Can't open display: `となり、挫けそうになったときに助けて頂いたＨＰのリンクです。皆さんも参考にしてください。


Docker Desktopの設定の確認

https://qiita.com/minato-naka/items/84508472c04f628e576e


WSLの導入時のトラブル

https://niwaka1535.hateblo.jp/entry/20230213/1676289180

WSL2のインストール

https://www.kkaneko.jp/tools/wsl/wsl2.html