ssh先で動くコンテナからx11アプリを動かす

X Window System についての説明は省きます。
間違っている箇所やご指摘等あれば仰っていただけると助かります:pray:
リモートホストと自宅PC間でssh接続している状況を想定します。
リモートホストはUbuntu20.04、自宅PCはWindows11です。
まず **ssh先のリモートホスト（x11クライアント）と自宅PC（x11サーバ）間のx11通信** について、
その後 **ssh先のリモートホスト上で動くコンテナ（x11クライアント）と自宅PC（x11サーバ）間のx11通信** について述べます。


## ssh先のリモートホスト（x11クライアント）と自宅PC（x11サーバ）間のx11通信

まずssh先のリモートホスト（x11クライアント）と自宅PC（x11サーバ）でのx11アプリの実行についてです。
以下のように設定を行います。

### ssh先のリモートホスト（x11クライアント）
`/etc/ssh/sshd_config` で以下の設定に変更します。

```:/etc/ssh/sshd_config
X11Forwarding yes
```

リモートホスト側で環境変数　`DISPLAY`　は自分でいじらなくて大丈夫だと思います。上記の設定に加え、次項で紹介するsshクライアント側でのx11転送を行う設定（sshの-Yオプションなど）を入れると、ssh接続時に自動で値が設定されると思います。

少し話はずれますが、wsl2（x11クライアント）とWindows（x11サーバ）という構成でx11通信を行う際は、wsl2側で`DISPLAY`の値に、WindowsのIPアドレスを設定をすることでx11通信を行うことができます。この際、WindowsのIPはipconfigなどで調べて設定してください。`localhost`と設定してはいけません、なぜならwsl2のlocalhostという意味になってしまうからです。あくまでx11サーバのIPアドレスを設定する必要があります。

~~しかしながらsshでx11通信を行う際はDISPlLAYの値が勝手にlocalhost:10.0とかに設定されると思いますが、これで問題なく通信できます。sshの場合は、sshを行った先のx11サーバのlocalhostという風に解釈してくれるのかな？って気がしてます。~~

↑ の説明間違っておりました:bow_tone1:
コメントで@ttdoda様が正しい解説をしてくださってるのでそちらを参考にしてください！
https://qiita.com/Atsuyaki_Tamago/items/64d9be136f09b3c49cdb#comment-51403eb193012f9895e0

### 自宅PC（x11サーバ）

sshでの設定と、x11のサーバアプリを起動するの2点を行う必要があります。

まずsshでの設定について、

~~調べるとsshする際に `ssh -X`　や `ssh -YC` などのオプションをつけるとよさそうです。
しかしながら **powershell** だとこのオプションをつけてもpowershell側のバグのためうまくx11転送が行うことができないようです（私もできませんでした、バージョンは　5.1.22621.436　です）。
そして **コマンドプロンプト** でもできませんでした。自分が何か間違ってるのかな？~~

↑ またまた間違っておりました:bow_tone1:
コメントで@ttdoda様が正しい解説をしてくださってるのでそちらを参考にしてください！
https://qiita.com/Atsuyaki_Tamago/items/64d9be136f09b3c49cdb#comment-51403eb193012f9895e0
使用するsshクライアントによって、sshクライアント側でDISPLAYの設定が必要かどうか変わってきそうです。

筆者はTeratermを用いてsshをし、teratermで以下のような設定を行うことで無事x11通信を行うことができました。（DISPLAYの値は設定せずに無事x11通信できました）

まずTeratermの設定からSSH転送を選択し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3040289/92b4490f-7fd8-34fb-f8a8-9c6393f940dd.png)

「リモートのXアプリケーションをローカルのXサーバに表示する」にチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3040289/9148c7ea-f41f-5374-8ca7-b6db7829ef6e.png)

これでsshでの設定は終了です。

次にx11のサーバアプリを起動するについてです。

いろいろあるかもしれませんが、筆者は **VcXsrv** を使いました。
「VcXsrv　インストール」などと調べれば記事が出てきますのでそちらを参考にしてください。

起動の方法についても割愛させていただきます。起動時のオプションで　**Disable access control** にチェックを入れることだけ忘れないでください。
これにて設定は終了です。

### 実行してみる

リモートホストにssh接続し、

```:リモートホスト
xeyes
```
xeyesを実行すると、自宅PCのディスプレイに

![xeyes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3040289/7f883874-6ffb-fe1a-056c-fad066d82ae4.png)

が表示されました！



## ssh先のリモートホスト上で動くコンテナ（x11クライアント）と自宅PC（x11サーバ）間のx11通信

いよいよ本題です。
自宅PC側では先ほどと同じ設定で大丈夫です（VcXsrvを起動するのを忘れないでください！）

### ssh先のリモートホスト

まずDockerイメージを作成します。あらかじめx11クライアントアプリをインストールしておきます。

```:リモートホスト:Dockerfile
# ubuntuのイメージを使用
FROM ubuntu:latest

# x11クライアントアプリをインストール
RUN apt-get update && apt-get install -y x11-apps

# コンテナはrootユーザで起動されるように設定
USER root
```

このイメージをbuildします。
tオプションをつけることによりイメージに名前をつけることができます。今回は「x11」と名付けました。
```:リモートホスト
sudo docker build ./ -t x11
```
それではコンテナを作成しbashを起動します（docker run でコンテナの作成からbashの起動まで以下のように一発でできます）。この際のオプションがポイントなのですが、このコマンドの下に説明を書いていきますね！

```:リモートホスト
sudo docker run   --rm   -it   --net=host   -e DISPLAY    -v $HOME/.Xauthority:/root/.Xauth_copy  x11 bash
```
`--net=host`オプションによりコンテナがネットワーク名前空間をホストと共有します。おそらく共有しない場合はまた必要な設定が変わってくると思いますが今回は触れません（すみません:bow_tone1:）

`-e DISPLAY` によりホストのDISPLAY環境変数をコンテナに共有します。

`-v $HOME/.Xauthority:/root/.Xauth_copy` によりホストの `$HOME/.Xauthority` ファイルをコンテナの`/root/`に`.Xauth_copy`という仮の名前で共有します。ここがポイントでそのままコンテナの`/root/`に`.Xauthority`という名前で共有してはいけません。
x11転送のためのx11認証が失敗してしまうからです（共有したファイルは所有者、所有グループが`$HOME/.Xauthority`と同じなのに、コンテナのユーザーはrootだからかな？と思います。）。

それでは進めます。
今状態としてはbashを起動しコンテナの中に入っている状態です。
後は先ほど作成された`/root/.Xauth_copy`の所有者、所有グループをrootに、名前を`/root/.Xauthority`に変更すればx11アプリが使えるようになるはずです！
ですが今は`-v $HOME/.Xauthority:/root/.Xauth_copy`により `/root/.Xauth_copy`はvolume mount されている状態なので直接いじるべきではないです。なのでコピーします。
```:リモートホスト上のコンテナ
cp /root/.Xauth_copy /root/.Xauthority
```
これで準備完了です！！！

`ll -a` で確認してもらえると分かりますが、`/root/.Xauthority` の所有者はすでにrootになっていると思います。

では実行できるか確認してみましょう！

### 実行してみる

```:リモートホスト上のコンテナ
xeyes
```
xeyesを実行すると、

![xeyes_docker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3040289/93b25b6f-a999-ffaa-43f4-d3b1c95759ef.png)

自宅PCの画面上に無事表示されました！！


ここまで読んでくださった方ありがとうございました！！
初めて書いた記事ということで温かい目で見て下さったら幸いです笑

ご指摘等あればぜひぜひコメントしてください！


参考資料

以下記事非常に参考になりました！
https://nnt339es.hatenablog.com/entry/2022/04/30/013450