WSL2 和 Docker 容器中运行 GUI 程序

loskyertt Unknown

1.WSL2 执行 GUI 程序(X11)

需要在 Windows 上安装MobaXterm,这里推荐安装中文版的(原版可以在官网下载):中文版 Mobaxterm。这个软件自带x11-server

然后只需要在 WSL2 (Linux 子系统发行版)中安装x11-apps即可。

对于Ubuntu

1
sudo apt install x11-apps -y

执行这条命令就能安装好配套的x11 apps,比如xclockxeyes

对于Arch

1
sudo pacman -S xorg

这条命令只是安装对于的x11-server,然后执行下面的命令:

1
sudo pacman -S xclock xeyes

这样直接在终端、VSCode WSL2中的终端或者MobaXterm中运行xclock或者xeyes就能显示 GUI 程序了。

1
xclock

如下图所示:

示例.png
示例.png

这样也能在 WSL2 中进行可是开发,比如用Pythonmatplotlib绘图等。

如果运行不成功的话,可以执行下面的命令试试:

1
DISPALY=<你的宿主机的IP>:0 xclock

比如:DISPALY=172.27.158.40:0 xclock


2.Docker 容器中执行 GUI 程序(X11)

整体操作方式跟在 WSL2 中是一样的,这里以 Docker 的ubuntu镜像为例子。

1
docker pull ubuntu
1
docker run -it --name=test-gui --env HTTP_PROXY=http:172.27.158.40:7890 --env HTTPS_PROXY=http:172.27.158.40:7890 ubuntu:latest

这里的--env HTTP_PROXY=http:172.27.158.40:7890 --env HTTPS_PROXY=http:172.27.158.40:7890是我配置的代理服务,172.27.158.40是宿主机的IP地址。是为了方便执行容器中一系列apt的命令。当然,也可以配置镜像源。

如果要配置镜像源,记得安装CA证书:

1
apt-get install ca-certificates

进入容器后,先进行更新,执行:

1
apt-get update

然后下载:

1
apt-get install x11-apps

这里要运行 GUI 程序,只能在MobaXtermVSCode中运行。

2.1 在MobaXterm中运行

1
DISPALY=<你的宿主机的IP>:0 xclock

如下图所示:

MobaXterm中运行.png
MobaXterm中运行.png

如果觉得麻烦,可以把DISPALY=<你的宿主机的IP>导入到环境变量中。

1
export DISPALY=<你的宿主机的IP>

如下图所示:

MobaXterm中运行.png
MobaXterm中运行.png

2.2 在 VSCode 中运行

需要通过Dev Containers扩展,进入到容器内部,然后直接执行命令即可:

1
xclock

如下图所示:

VSCode中运行.png
VSCode中运行.png

注意:如果是在 Linux 系统下,在 VSCode 中运行可能会出现这样的错误:

1
2
3
root@710c5762df8e:~# xclock
Authorization required, but no authorization protocol specified
Error: Can't open display: :0

意味着当前用户或容器中的环境没有被授权访问X11显示服务器(DISPLAY=:0)。这是一个典型的X11权限问题。

只需要在宿主机上运行以下命令,允许容器的用户访问显示服务:

1
xhost +local:docker

这样再运行xclock就能成功了。

如果希望更安全,只允许特定用户访问,可以指定用户(比如这里指定root用户):

1
xhost +SI:localuser:root

3.Docker 容器中执行 GUI 程序(Wayland)

运行容器时,挂载 Wayland 必需的 Socket 和环境变量:

1
docker run -it --name=test-wayland -e WAYLAND_DISPLAY=$WAYLAND_DISPLAY -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR -v $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY --device=/dev/dri ubuntu:latest

解释:

  • -e WAYLAND_DISPLAY=$WAYLAND_DISPLAY:传递 Wayland 显示环境变量(通常为 wayland-0)。
  • -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR:传递 Wayland 的运行时目录。
  • -v $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:挂载 Wayland Socket 文件。
  • --device=/dev/dri:允许容器访问 GPU。

3.1 在容器中验证 Wayland 配置

进入容器后,验证环境是否正确:

  1. 检查 WAYLAND_DISPLAY

    1
    echo $WAYLAND_DISPLAY

    应返回 wayland-0 或类似内容。

  2. 检查 XDG_RUNTIME_DIR

    1
    2
    echo $XDG_RUNTIME_DIR
    ls $XDG_RUNTIME_DIR

    应包含 wayland-0


3.2 运行 Weston-terminal(测试)

  1. 安装 Weston 系列程序:

    1
    apt install -y weston
  2. 运行 Weston-terminal 测试:

    1
    weston-terminal

    如果配置正确,应该会打开一个终端窗口。如下图所示:

    Snipaste_2024-12-08_13-17-50.png
    Snipaste_2024-12-08_13-17-50.png


3.3 补充:切换 Wayland/X11 环境

  • 如果你希望 gedit 和其他应用也通过 Wayland 运行,可以启动它们时强制启用 Wayland:
    1
    WAYLAND_DISPLAY=wayland-0 gedit
  • 如果继续使用 X11,则无需修改。
  • Title: WSL2 和 Docker 容器中运行 GUI 程序
  • Author: loskyertt
  • Created at : 2024-11-27 12:14:33
  • Updated at : 2024-12-08 06:30:35
  • Link: https://redefine.ohevan.com/2024/11/27/WSL-容器GUI/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments