手順としては以下のような感じになります。
前準備
X11サーバ(XQuarts)をセットアップ。
# XQuarts をインストール
brew cask install xquartz
# Dockerから接続するのに必要な設定
## 「環境設定→ セキュリティ→ 接続を認証」 をチェック
defaults write org.macosforge.xquartz.X11 no_auth -bool false
## 「環境設定→ セキュリティ→ ネットワーク・クライアントからの接続を許可する」 をチェック
defaults write org.macosforge.xquartz.X11 nolisten_tcp -bool false
# 必須じゃないけど個人的に有用な設定
## 「環境設定→ 入力→ OptionキーでAlt_LとAlt_Rを送信」 をチェック
defaults write org.macosforge.xquartz.X11 option_sends_alt -bool true
## XQuartz 起動時に勝手に xterm が起動しないようにする(デフォルト値は /opt/X11/bin/xterm)
defaults write org.macosforge.xquartz.X11 app_to_run ""
## xterm とか起動したときのデフォルトシェルを変更
defaults write org.macosforge.xquartz.X11 login_shell "/bin/bash"
## OpenGL が使えるようにする
defaults write org.macosforge.xquartz.X11 enable_iglx -bool true
# 確認方法
defaults read org.macosforge.xquartz.X11
以上で準備OK。今後は XQuarts を起動してさえあれば X11 が使えます。
あとよく使うなら XQuartz の自動起動をしておくなど。
Docker で X11 アプリを実行してみる
実行時は DISPLAY
環境変数にホスト名を設定し、~/.Xauthority
をボリュームマウントしてやればOKです。
docker run --rm -e DISPLAY="$(hostname):0" -v ~/.Xauthority:/root/.Xauthority alpine sh -c 'apk add --no-cache xeyes && xeyes'
とか、OpenGL を使ったデモなら↓こんな感じでとりあえず動きます。
docker run --rm -e DISPLAY="$(hostname):0" -v ~/.Xauthority:/root/.Xauthority alpine sh -c 'apk add --no-cache mesa-demos && glxgears'
注意点
自分がハマった点なのですが、XQuarts を初めて起動する以前に
docker run -v ~/.Xauthority:/root/.Xauthority 〜
を実行したことがあると、~/.Xauthority
というパスに空ディレクトリが作成されてしまい、その後のX11アプリケーションの実行に支障が出ます。
もし以下のような状態になってしまっているようなら
$ ls -ld ~/.Xauthority*
drwxr-xr-x 2 kawaz staff 64 2020-04-30 13:11:11.716 /Users/kawaz/.Xauthority
-rw------- 1 kawaz staff 49 2020-04-30 13:16:24.357 /Users/kawaz/.Xauthority-n
rm -rf ~/.Xauthority*
してから XQuarts の再起動をしましょう。
意図してその状態にしているなら docker run
の引数を -v ~/.Xauthority-n:/root/.Xauthority
に変えてやれば動きます。まぁ意図している人には釈迦に説法ですが、意図してない人が大抵だろうから通常は一度削除しとく対処で良いと思います。
参考
基本的には参考エントリと同じこと書いてますが ~/.Xauthority
の辺りでハマったので個人的整理も兼ねてこのエントリを書きました。