WSLgとdocker composeで全部やる
概要
メイン機の一台をLinuxからWindowに乗り換えたくなったので、簡単に移行できて、簡単に戻れるように、WSLgとdocker composeを使っていろいろなGUIアプリをコンテナ上で実行する環境構築をしました。docker-composeファイルだけでありとあらゆることをしたいのです。 そのうえで調べたことをまとめます。コンフィグ生成のSPAを作りましたので、GUIアプリコンテナの設定だけ知りたい方はDesktop Composeへ。
前提
- Windows11
- WSLg
- Ubuntu
WSLgの下調べ
X Server
ys@laptop ~> echo $DISPLAY
:0
ys@laptop ~> ls -lh /tmp/.X11-unix/X0
srwxrwxrwx 1 ys users 0 Jan 23 15:00 /tmp/.X11-unix/X0=
X Serverのunix socketは普通に/tmp/.X11-unix/
以下にあります。
ys@laptop ~> env | grep XAUTHORITY
ys@laptop ~ [0|1]> xauth list
xauth: file /home/ys/.Xauthority does not exist
認証のためのXAUTHORITYはありません。
ys@laptop ~> xhost
access control disabled, clients can connect from any host
SI:localuser:wslg
デフォルトで無認証となっています。
Wayland
ys@laptop ~> env | egrep "(XDG_RUNTIME_DIR|WAYLAND_DISPLAY)"
WAYLAND_DISPLAY=wayland-0
XDG_RUNTIME_DIR=/mnt/wslg/runtime-dir
ys@laptop ~> ls -lh $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY
srwxrwxrwx 1 ys users 0 Jan 23 15:00 /mnt/wslg/runtime-dir/wayland-0=
Waylandのソケットは、/mnt/wslg/runtime-dir/wayland-0
にあります。
PulseAudio
ys@laptop ~> env | egrep "(PULSE_SERVER|PULSE_COOKIE)"
PULSE_SERVER=/mnt/wslg/PulseServer
Pulse Audioのソケットは、/mnt/wslg/PulseServer
にあります。
こちらもCOOKIEはなく、無認証です。
User session dbus
WSLgではsystemdが動いていないので、user session busは使えません。
各リソースへのアクセスは無認証なので、比較的シンプルにコンテナ上のGUIアプリからアクセスできます。
Docker Rootlessのインストール
Rootfull Dockerでも実現できますが、安心して使えるようにWSLgのDocker Rootlessをインストールし、docker composeを導入します。
sudo apt update
sudo apt upgrade -y
sudo apt install -y uidmap fuse-overlayfs
export SKIP_IPTABLES=1; curl -fsSL https://get.docker.com/rootless | sh
fuse-overlayfs
をインストールしないと、docker create
のたびにイメージをフルコピーするので、数十秒かかってしまいます。
自動起動するように~/.bash_profile
と~/.bashrc
と~/.bash_logout
に以下を追加します。
# DOCKER ROOTLESS SETTING
export PATH=$HOME/bin:$PATH
export DOCKER_HOST=unix:///mnt/wslg/runtime-dir/docker.sock
# DOCKER ROOTLESS LAUNCH
dockerds=`ps -ef | grep "dockerd-rootless.sh"| grep -v grep | wc -l`
if [ $dockerds = 0 ]; then
rm $XDG_RUNTIME_DIR/docker.sock $XDG_RUNTIME_DIR/docker.pid
rm -rf $XDG_RUNTIME_DIR/docker
dockerd-rootless.sh --iptables=false &
fi
# TERMINATE ROOTLESS DOCKER
DOCKER_PID_FILE=${XDG_RUNTIME_DIR}/docker.pid
if [ -e $DOCKER_PID_FILE ]; then
kill `cat $DOCKER_PID_FILE`
fi
これでUbuntuのterminalを起動すれば、Docker Rootlessが立ち上がります。
Docker Compose導入
mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
docker compose version
アプリ準備
ベースとなる下記を保存してください。
version: "3.9"
services:
ubuntubase:
build: https://github.com/ysuito/desktop-compose.git#master:src/ubuntubase_ja
image: ubuntubase
container_name: ubuntubase
Desktop Composeでアプリのconfigを生成して、local-compose.yamlに追加してください。
version: "3.9"
services:
ubuntubase:
build: https://github.com/ysuito/desktop-compose.git#master:src/ubuntubase_ja
image: ubuntubase
container_name: ubuntubase
gedit:
working_dir: /home/user
environment:
- UID=1000
- GID=1000
- DISPLAY=:101
- WAYLAND_DISPLAY
- XDG_RUNTIME_DIR=/tmp
volumes:
- type: bind
source: /tmp/.X11-unix/X0
target: /tmp/.X11-unix/X101
- type: bind
source: "${XDG_RUNTIME_DIR}/wayland-0"
target: /tmp/wayland-0
cap_add:
- CHOWN
- SETUID
- SETGID
- DAC_OVERRIDE
cap_drop:
- ALL
command:
- bash
- -c
- "groupadd -g $${GID} user && useradd -s /bin/bash -u $${UID} -g user user && chown -R user:user /home/user; su user -c \"gedit\""
network_mode: host
build: https://github.com/ysuito/desktop-compose.git#master:src/gedit
image: gedit
container_name: gedit
depends_on:
- ubuntubase
解説
イメージの依存関係
depends_on:
- ubuntubase
depends_on
にビルド時の依存イメージを追加すると簡易的な依存関係を記述できます。
白いウィンドウ枠への対処
X Serverを差して起動するとウィンドウ枠が白くなります。ダークテーマを利用していると非常に気になるので、極力native waylandで起動するようにします。
environment:
- WAYLAND_DISPLAY
- XDG_RUNTIME_DIR=/tmp
volumes:
- type: bind
source: "${XDG_RUNTIME_DIR}/wayland-0"
target: /tmp/wayland-0
Waylandソケットを共有して、2つの環境変数で接続先を伝えます。
さらにアプリ側にも、下記のように接続方法を指示します。
- Firefoxの場合は
MOZ_ENABLE_WAYLAND=1
- QTの場合は
QT_QPA_PLATFORM=wayland
- GTKの場合は
GTK_SESSION_TYPE=wayland
- Chrome, Electron系はコマンド引数を指定
--enable-features=UseOzonePlatform --ozone-platform=wayland
Build
docker build --network=host -t gedit https://github.com/ysuito/desktop-compose.git#master:src/gedit
Run
ステートレスに起動したい場合は
docker compose -f local-compose.yaml run --rm -d IMAGE
ステートフルに起動したい場合は
docker compose -f local-compose.yaml up -d IMAGE
Update
docker build --no-cache --network=host -t gedit https://github.com/ysuito/desktop-compose.git#master:src/gedit
Windows側からのショートカット
C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\desktop-compose
に下記内容でショートカットを作成すれば簡単に起動できます。
C:\Windows\System32\wslg.exe ~ -d Ubuntu bash -c "docker compose -f local-compose.yml run --rm -d gedit"
Custom App
画面共有設定や音声共有設定を取り除いた、アプリ特有の設定の基本部分は下記のように簡潔です。
gedit:
build: https://github.com/ysuito/desktop-compose.git#master:src/gedit
image: gedit
container_name: gedit
depends_on:
- ubuntubase
command: ["su user -c \"gedit\""]
build contextとして、ローカルディレクトリ、Githubリポジトリを指定でき、imageとしてDockerHubのイメージを指定できます。サンプル:geditのDockerfile
リモートリソースを使う
xpraを動かすコンテナ追加することでリモート上で実行するアプリの画面をローカルに転送することができます。詳細はこちらをご覧ください。
リモートホストとのファイル同期
複数の端末でファイル同期したい場合は、Syncthingコンテナを追加することで実現できます。
syncthing:
image: syncthing/syncthing
container_name: syncthing
hostname: HOSTNAME
ports:
- 127.0.0.1:8384:8384
- target: 22000
published: 22000
protocol: tcp
mode: host
- target: 22000
published: 22000
protocol: udp
mode: host
volumes:
- type: bind
source: "${HOME}"
target: /var/syncthing
network_mode: host
environment:
- PUID=0
- PGID=0
あとは、bashrcなどで起動設定等を追加してください。
# SYNCTHING LAUNCH
syncthings=`docker ps | grep "syncthing"| wc -l`
if [ $syncthings = 0 ]; then
(sleep 3 && docker compose -f ~/local-compose.yml run --rm -d syncthing) &
fi
その他
sandbox化
怪しいサイトを見たりする専用ブラウザを作りたければ、UID/GIDを2000など他のアプリが利用していないものにすれば、仮にそのコンテナが破られても、他のコンテナのリソースやホストのリソースにはアクセスできないので、安心感が増します。ただ、Xサーバなどは共有しているので、画面のぞき見やクリップボード盗聴などの可能性は残ります。WSLg System Distroは各User Distro毎に立ち上がるようなので、専用Distroを用意すれば完璧な対策になるかもしれません。
制限
- WSLg上のGUIコンテナアプリに日本語入力ができない(
/tmp/fcitx-socket-:0
とか共有したりいろいろやりましたがダメでした。WSLg側で対処されることを期待)。 - リモートでの音声が利用できない。
WSLgのGPU利用について
今回検証に使ったPCがIntel第五世代CPUだったので、vGPU化のドライバが導入できず無理やり動かしているので、GUIアプリ表示時はCPU使用率がネイティブ起動より2~3倍高くなります。最新のPCならGPUアクセラレーションが効いてよりストレスなく動くと思いますが、この点は検証できていません。
まとめ
一部若干制限はありますが、WSLgとdocker composeで大方全部できそうです。WSLgの発展を切望しております。ホスト環境を汚したくない方や、WindowsとLinuxを横断的に利用したい方は参考にしてみてください。
参考
Discussion