Rootless Docker はホスト側の権限を絞れて便利ですが、GUI アプリ(X11)をコンテナから表示したいときに少しだけハマりどころがあります。
この記事では ホストの X サーバに対して、コンテナ側へ xauth の Cookie を渡し、rootless Docker コンテナ内から X11 アプリを起動する手順をまとめます。
前提
- ホストで X サーバが動いている(Linux の Xorg / Xwayland 等)
- コンテナからホストの X サーバへ TCP 接続できる(後述の
--network hostを使用) - rootless Docker を利用している(ただし手順自体は通常 Docker でも概ね同じ発想)
全体像(何をしているか)
X11 のアクセス制御はざっくり次の2段です。
- どの DISPLAY に接続するか(例:
10.0.2.2:10) - 接続を許可する認証情報(MIT-MAGIC-COOKIE)を渡すか
この記事の手順は、ホストが保持している MIT-MAGIC-COOKIE-1 をホスト側で確認し、コンテナ側で xauth add して .Xauthority を作る、という流れです。
1. ホストで X11 の Cookie を確認する
まずホストで、今の DISPLAY に紐づく Cookie を確認します。
$ xauth list "$DISPLAY"
hostname/unix:10 MIT-MAGIC-COOKIE-1 0a1b2c...
ここで出てくる 0a1b2c... が Cookie です。
あとでコンテナ側に xauth add するので、コピーしておきます。
補足
hostname/unix:10の末尾:10はディスプレイ番号です。環境によって:0だったり:1だったりします。
2. コンテナを起動する(rootless Docker)
次にコンテナを起動します。例として wine イメージを使っていますが、任意のイメージで OK です。
$ docker run -it --rm --name wine-x11 \
--network host \
-e DISPLAY=host.docker.internal:12.0 \
-v ./root:/root \
-v ./work:/work \
wine bash
オプションの意図
--network hostX サーバへ到達しやすくするためにホストネットワークを使用します(rootless 環境で特に手っ取り早い)。-e DISPLAY=host.docker.internal:12.0コンテナ内のデフォルト DISPLAY 設定。あとで実際に使う DISPLAY は手元環境に合わせて切り替えます。-v ./root:/rootコンテナ内の/rootを永続化しておくと.Xauthorityを保持できて便利です(毎回xauth addしたくない場合)。-v ./work:/work作業ディレクトリ用(任意)。
注意
host.docker.internalは環境によって効かない場合があります。その場合でも、後段のDISPLAY=10.0.2.2:10のように ホスト側 IP を明示すれば進められることが多いです。
3. コンテナ内で xauth add して Cookie を登録する
コンテナに入ったら、ホストで見た Cookie を使って xauth add します。
# xauth add 10.0.2.2:10 MIT-MAGIC-COOKIE-1 "${cookie}"
10.0.2.2:10の部分は「コンテナから見たホスト」と「ディスプレイ番号」です。"${cookie}"にはホストで確認した0a1b2c...を入れます。
よく見る warning について
実行時に以下が出ることがあります。
xauth: file /root/.Xauthority does not exist
これは 単に .Xauthority がまだ無いだけなので、warning として無視して OKです。
(xauth add によってファイルが新規作成されます。)
4. xev で疎通確認する
最後に X11 クライアントを起動して、画面が出るか確認します。ここでは xev を例にします。
# DISPLAY=10.0.2.2:10 xev
ウィンドウが開き、キー入力やマウスイベントが流れてくれば成功です 🎯
うまくいかないときのチェックポイント
-
DISPLAY 番号が合っているか
- ホストの
xauth list "$DISPLAY"の末尾(:10など)と合わせる
- ホストの
-
xauth addの宛先が合っているか10.0.2.2があなたの環境で「コンテナ → ホスト」になっているか
-
X サーバが TCP 接続を受け付けているか
- 環境によっては
unix domain socket前提で、TCP が閉じている場合があります
- 環境によっては
-
Wayland 環境の場合
- Xwayland 経由になっていることが多く、DISPLAY が
:0ではなく:1などになりがちです
- Xwayland 経由になっていることが多く、DISPLAY が
まとめ
rootless Docker でも、ポイントは単純で、
- ホストの
MIT-MAGIC-COOKIEを取り出す - コンテナで
xauth addして.Xauthorityを作る - 正しい
DISPLAYを指定して X11 アプリを起動する
これだけで X11 アプリを動かせます。