2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DockerからChromeをホストPCにWaylandで表示する方法

Last updated at Posted at 2024-08-18

はじめに

この記事ではDockerコンテナで起動するChromeブラウザをホストPC側のWaylandを使って表示する方法について確認する。

Ubuntu 24.04をはじめとする最近のLinuxディストリビューションでは、X11の代わりにWaylandがディスプレイサーバーとしてデフォルトに設定されています。また、組み込み機器においても、Waylandはその軽量性と効率性から広く利用されている。

DockerコンテナからWaylandアプリケーションをホストPCに直接表示するためには、ホストPCのWaylandディスプレイサーバにコンテナ内のアプリケーションがアクセスできるように設定する必要があります。まずは、シンプルなテスト環境を構築し、WaylandアプリをホストPCで表示させることを確認します。最後に、ChromeブラウザをホストPCで表示させる。

動作環境

項目 ホストPC Dockerコンテナ
OS Ubuntu 24.04 Ubuntu 24.04
ディスプレイサーバー Wayland n/a

Waylandをディスプレイサーバーとして選択し、Ubuntuにログインする方法は、下記が詳しい。

WaylandアプリをホストPCで表示する

Waylandがディスプレイサーバーとして動作するUbuntu24.04などの環境をホスト側に用意しているものとして進める。

ホストPCの準備

XDG_RUNTIME_DIRの確認

ホストPCでXDG_RUNTIME_DIRが正しく設定されているか確認する。

echo $XDG_RUNTIME_DIR

通常、Ubuntuではこのディレクトリは /run/user/$(id -u) だ。

Wayland環境の確認

ホストPCがWaylandセッションで動作していることを確認します。Ubuntu24.04であれば、Gnomeを使っている場合、デフォルトでWaylandが使われている。
ホストPCでXDG_SESSION_TYPEwaylandであることを確認する

echo $XDG_SESSION_TYPE

wayland と出力されるか確認する。x11と表示された場合にはログイン時にX11が利用されている。

GPUの確認

ホストPCのGPUを確認する

lspci -v | grep -i --color 'vga\|3d\|2d'

GPUとしてIntel Chipが認識されている

IntelのGPUが確認される
00:02.0 VGA compatible controller: Intel Corporation Raptor Lake-S GT1 [UHD Graphics 770] (rev 04) (prog-if 00 [VGA controller])

Dockerの用意

ホストPCにDockerがインストールされていることを確認する。インストールされていない場合は下記のコマンドでインストールする。

sudo apt-get update
sudo apt-get install docker.io

Waylandソケットの確認

Waylandは/run/user/$(id -u)/wayland-0にソケットを作成する。このソケットにコンテナからアクセスできるようにする。

file /run/user/$(id -u)/wayland-0

/run/user/1000/wayland-0: socketのようにWaylandソケットの存在が確認できる

Dockerコンテナの設定

Waylandソケットのマウント

コンテナ内からホストのWaylandソケットにアクセスできるように、ソケットをボリュームとしてマウントする。また、Dockerコンテナで XDG_RUNTIME_DIR をホストPCと同じ値に設定する。

例えば、docker runコマンドに以下のオプションを追加する。

-v /run/user/$(id -u)/wayland-0:/run/user/$(id -u)/wayland-0:rw \
-e WAYLAND_DISPLAY=wayland-0 \
-e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \

WaylandのソケットをマウントしてDocker側からも利用するためにコンテナ内ユーザーのUID/GIDをホストPC側のUID/GIDと揃える必要がある

Wayland対応アプリケーションのインストール

テスト用のWayland対応アプリケーションをコンテナ内にインストールする。weston-terminalをここではインストールする。

下記のようなDockerfileを適当なディレクトリに作成する。

FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
    weston \
    && rm -rf /var/lib/apt/lists/*

Dockerイメージのビルド

wayland-testと名前をつけてDockerイメージを作成する

docker build -t wayland-test .

テスト環境の構築と実行

Dockerコンテナの起動

コンテナ内ユーザーのUID/GIDをホストPC側と揃えて、ホストのWaylandソケットをマウントしコンテナを起動する。

docker run -it \
--user $(id -u):$(id -g) \
-v /run/user/$(id -u)/wayland-0:/run/user/$(id -u)/wayland-0:rw \
-e WAYLAND_DISPLAY=wayland-0 \
-e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \
--name wayland-test-container \
wayland-test /bin/bash

アプリケーションの実行

コンテナ内でweston-terminalを実行する。

Dockerコンテナで実行する
weston-terminal

表示確認

成功の場合にはweston-terminalがホストPCのWaylandセッションに表示される。

Screenshot from 2024-08-17 16-34-50.png

ホストPCがX11セッションだった場合などはエラーとなる
failed to connect to Wayland display: Connection refused
failed to create display: Connection refused

トラブルシューティング

表示されない場合

コンテナがホストPCのWaylandソケットに正しくアクセスできているか、ソケットのパスとWAYLAND_DISPLAY変数が正しいかを再確認する。

権限の問題

Waylandソケットにアクセスするため、ホストPCのユーザーIDと同じUIDをDockerコンテナに設定する必要がある。これは、--user $(id -u):$(id -g)オプションで設定する。

ChromeブラウザをホストPCに表示する

ホストPCがX11の場合との違い

dbus

X11を使用する場合、dbus-x11パッケージをインストールする必要がある。X11環境で動作するDBusセッションバスを提供するためだったが、Waylandでは通常のdbusパッケージで良い。

Chromeの起動方法

Waylandでは--ozone-platform-hint=waylandオプションを使ってChromeにWaylandを使用するよう指示する。また--enable-wayland-imeを追加することでWayland上で日本語入力メソッド(IME)のサポートを有効にする。

Dockerfile

Dockerfile
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

# 必要なパッケージをインストール
RUN apt-get update && \
    apt-get install -y wget pulseaudio socat alsa-base \
    libcanberra-gtk-module libcanberra-gtk3-module \
    fonts-ipafont-gothic fonts-ipafont-mincho fonts-noto-cjk \
    language-pack-ja dbus && \
    wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
    apt-get install -y ./google-chrome-stable_current_amd64.deb --no-install-recommends && \
    apt-get install -y weston mesa-utils sudo &&\
    apt-get clean && rm -rf /var/lib/apt/lists/*

RUN echo "#!/bin/bash\n\
set -e\n\
sudo /etc/init.d/dbus start || { echo 'Failed to start dbus'; exit 1; }\n\
export XDG_RUNTIME_DIR=/run/user/\$(id -u)\n\
sudo mkdir -p \$XDG_RUNTIME_DIR || { echo 'Failed to create XDG_RUNTIME_DIR'; exit 1; }\n\
sudo chmod 700 \$XDG_RUNTIME_DIR || { echo 'Failed to chmod XDG_RUNTIME_DIR'; exit 1; }\n\
sudo chown \$(id -un):\$(id -gn) \$XDG_RUNTIME_DIR || { echo 'Failed to chown XDG_RUNTIME_DIR'; exit 1; }\n\
export DBUS_SESSION_BUS_ADDRESS=unix:path=\$XDG_RUNTIME_DIR/bus\n\
dbus-daemon --session --address=\$DBUS_SESSION_BUS_ADDRESS --nofork --nopidfile --syslog-only &\n\
exec \"\$@\"" > /start.sh && chmod +x /start.sh

# ホストのUIDとGIDを利用してユーザーを作成する
ARG USER_ID
ARG GROUP_ID

# 既存のグループを確認して、なければ作成
RUN if ! getent group $GROUP_ID >/dev/null; then \
        groupadd -g $GROUP_ID hostgroup; \
    fi

# 既存のUIDに対応するユーザーがいない場合、新規ユーザーを作成して、PWなしでsudoを許可
RUN USER_NAME=$(getent passwd $USER_ID | cut -d: -f1) && \
    if [ -z "$USER_NAME" ]; then \
        USER_NAME="hostuser"; \
        useradd -u $USER_ID -g $GROUP_ID -m $USER_NAME; \
    fi && \
    echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# google-chrome を $USER_ID で実行
USER $USER_ID
CMD ["/start.sh", "google-chrome", "--disable-dev-shm-usage", " --ozone-platform-hint=wayland", "--enable-wayland-ime"]

Dockerイメージを作成

ホストPCで利用しているUIDとGIDを指定してubuntu24_waychromeという名前をつけてDockerイメージを作成する。

docker build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) -t ubuntu24_waychrome .

Dockerコンテナを起動

docker run -it --rm \
  --name ubuntu24_waychrome \
  -v /run/user/$(id -u)/wayland-0:/run/user/$(id -u)/wayland-0:rw \
  -e WAYLAND_DISPLAY=wayland-0 \
  -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \
  --env="PULSE_SERVER=unix:${XDG_RUNTIME_DIR}/pulse/native" \
  --volume="${XDG_RUNTIME_DIR}/pulse/native:${XDG_RUNTIME_DIR}/pulse/native" \
  --volume="/etc/machine-id:/etc/machine-id:ro" \
  --volume="/run/user/$(id -u)/pulse:/run/user/$(id -u)/pulse" \
  --network=host \
  --device /dev/dri \
  --cap-add=SYS_ADMIN --security-opt seccomp=unconfined \
  ubuntu24_waychrome

Chromeの表示確認

YoutubeでBig Buck Bunnyが音声つきで再生できた。

Screenshot from 2024-08-18 15-31-29.png

chrome://versionでChromeのバージョンと起動オプションを確認する

Screenshot from 2024-08-18 15-32-31.png

chrome://gpuでWaylandを利用が確認できる

Screenshot from 2024-08-18 15-34-36.png

chrome://gpuでハードウェアアクセラレーションがEnable有効であることが(but at reduced performance:しかしパフォーマンスは落ちている)確認できる

Screenshot from 2024-08-18 15-28-01.png

ハードウェアアクセラーションの問題

DockerコンテナからChromeブラウザを起動すると下記のようにlibEGLwarningが表示されている。/dev/dri/renderD128へのアクセス権限がない問題の解決が必要そうだ。

 * Starting system message bus dbus                                      [ OK ]
libEGL warning: failed to open /dev/dri/renderD128: Permission denied

libEGL warning: failed to open /dev/dri/renderD128: Permission denied

ハードウェアアクセラレーションの解決

Dockerイメージを/bin/bash付きで起動して/dev/dri/renderD128を確認する。

ホストPCから/bin/bash付きでコンテナを起動する
docker run -it --rm \
  --name ubuntu24_waychrome \
  -v /run/user/$(id -u)/wayland-0:/run/user/$(id -u)/wayland-0:rw \
  -e WAYLAND_DISPLAY=wayland-0 \
  -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \
  --env="PULSE_SERVER=unix:${XDG_RUNTIME_DIR}/pulse/native" \
  --volume="${XDG_RUNTIME_DIR}/pulse/native:${XDG_RUNTIME_DIR}/pulse/native" \
  --volume="/etc/machine-id:/etc/machine-id:ro" \
  --volume="/run/user/$(id -u)/pulse:/run/user/$(id -u)/pulse" \
  --network=host \
  --device /dev/dri \
  --cap-add=SYS_ADMIN --security-opt seccomp=unconfined \
  ubuntu24_waychrome /bin/bash
Dockerコンテナで確認
ls -la /dev/dri/renderD128
crw-rw---- 1 root systemd-resolve 226, 128 Aug 18 06:49 /dev/dri/renderD128

エラーはコンテナ内のChromeがWaylandディスプレイサーバーに接続しようとしたときに、/dev/dri/renderD128デバイスファイルにアクセスする権限が不足している。Chromeを起動するユーザーがsystemd-resolveに所属している必要がある。

Dockerfileの修正

usermod -aG systemd-resolve $USER_NAMEsystemd-resolveのグループにユーザを追加することで/dev/dri/renderD128へのアクセス権を追加する

修正したDockerfile
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

# 必要なパッケージをインストール
RUN apt-get update && \
    apt-get install -y wget pulseaudio socat alsa-base \
    libcanberra-gtk-module libcanberra-gtk3-module \
    fonts-ipafont-gothic fonts-ipafont-mincho fonts-noto-cjk \
    language-pack-ja dbus && \
    wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
    apt-get install -y ./google-chrome-stable_current_amd64.deb --no-install-recommends && \
    apt-get install -y weston mesa-utils sudo &&\
    apt-get clean && rm -rf /var/lib/apt/lists/*

RUN echo "#!/bin/bash\n\
set -e\n\
sudo /etc/init.d/dbus start || { echo 'Failed to start dbus'; exit 1; }\n\
export XDG_RUNTIME_DIR=/run/user/\$(id -u)\n\
sudo mkdir -p \$XDG_RUNTIME_DIR || { echo 'Failed to create XDG_RUNTIME_DIR'; exit 1; }\n\
sudo chmod 700 \$XDG_RUNTIME_DIR || { echo 'Failed to chmod XDG_RUNTIME_DIR'; exit 1; }\n\
sudo chown \$(id -un):\$(id -gn) \$XDG_RUNTIME_DIR || { echo 'Failed to chown XDG_RUNTIME_DIR'; exit 1; }\n\
export DBUS_SESSION_BUS_ADDRESS=unix:path=\$XDG_RUNTIME_DIR/bus\n\
dbus-daemon --session --address=\$DBUS_SESSION_BUS_ADDRESS --nofork --nopidfile --syslog-only &\n\
exec \"\$@\"" > /start.sh && chmod +x /start.sh

# ホストのUIDとGIDを利用してユーザーを作成する
ARG USER_ID
ARG GROUP_ID

# 既存のグループを確認して、なければ作成
RUN if ! getent group $GROUP_ID >/dev/null; then \
        groupadd -g $GROUP_ID hostgroup; \
    fi

# 既存のUIDに対応するユーザーがいない場合、新規ユーザーを作成して、PWなしでsudoを許可
RUN USER_NAME=$(getent passwd $USER_ID | cut -d: -f1) && \
    if [ -z "$USER_NAME" ]; then \
        USER_NAME="hostuser"; \
        useradd -u $USER_ID -g $GROUP_ID -m $USER_NAME; \
    fi && \
    echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \
    # /dev/dri/renderD128にアクセス権を追加
    usermod -aG systemd-resolve $USER_NAME

# google-chrome を $USER_ID で実行
USER $USER_ID

CMD ["/start.sh", "google-chrome", "--disable-dev-shm-usage", " --ozone-platform-hint=wayland", "--enable-wayland-ime"]

Chromeの表示確認

修正したDockerファイルで作成したDockerイメージからコンテナを起動する。chrome://gpuの出力はGPUのハードウェアアクセラレーションに制限がないことを示している。

Screenshot from 2024-08-18 16-31-38.png

WebGLのベンチマークのSpace Rocksでテストすると、たまに60fpsを切る場合もあるが、ほぼ60fpsをキープして表示される

Screenshot from 2024-08-18 16-48-00.png

蛇足

Wayland環境でスクリーンショットを撮りたい場合

gnome-screenshotをインストール
sudo apt-get install gnome-screenshot

メニューからGUIアプリを起動可能

image.png

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?