我假设:
我将使用
podman,但你可以通过在每个命令中将podman替换为docker来复制,我只是喜欢podman并且从未使用过docker。
我的系统:Opensuse Tumbleweed与
kde [Intel Optimus笔记本电脑]。
解决方案
应用程序需要向Xserver请求显示其图形用户界面元素。而为了安全起见,有一个授权系统。
这个授权系统被称为xauth。xauth通常将会话cookie存储在/home/username/.Xauthority文件中(通常但不总是)。
检查当前正在使用的cookie
xauth list
输出将如下所示,
localhost.localdomain/unix:0 MIT-MAGIC-COOKIE-1 99aaccf2d83177ddf581e2989ebbcea1
如果Xauthority文件不在通常的位置,请检查正在使用的授权文件。
xauth
输出将类似于这样,如果不使用标准文件的话,
Using authority file /run/user/1000/xauth_Abcde
我们需要向容器提供这两个东西,
-
MIT-MAGIC-COOKIE-1 - 现在只需将其视为协议或标识符。这对于每个会话都是恒定的。
-
99aaccf2d83177ddf581e2989ebbcea1 - 这个32位字母密钥是会话密钥,或者你想给它起的任何花哨的名字。密钥对于每个会话都是唯一的。
现在,为了解决与显示相关的问题,我们需要执行以下五个步骤:
1. 如果容器中不存在,请创建一个 .Xauthority 文件,就像我们的示例(debian)一样。
2. 将我们的会话密钥和协议添加到我们创建的 .Xauthority 文件中。
3. 将 DISPLAY 环境变量传递给容器。
4. 将主机的 Xserver socket(通常位于 /tmp/.X11-unix)挂载到容器中。
5. 将网络设置为 "host"(用于显示渲染)。
这五个步骤将解决所有与显示相关的问题。
配置 - 示例场景
示例中通过容器运行firefox图形界面。
待办事项
1. 创建一个.Xauthority文件
在Containerfile中执行RUN touch .Xauthority
2. 将我们的会话密钥和协议添加到我们创建的.Xauthority文件中
两者都作为环境变量传递
在Containerfile中设置协议:ENV PROTOCOL=MIT-MAGIC-COOKIE-1
将会话密钥作为参数传递给podman run
:--env KEY=$(xauth list | sed '2,$d'| tr -d '\n' | tail -c 32) \
(无法在Containerfile中作为常量传递,因为每个会话都会更改)
然后通过Containerfile中的CMD xauth add ${HOST}:0 $PROTOCOL $KEY
将其添加到.Xauthority中
3. 将DISPLAY环境变量传递给容器
作为参数传递给podman run
命令 --env DISPLAY \
4. 将Xserver套接字(通常位于/tmp/.X11-unix)挂载到容器中
作为参数传递给podman run
命令 --mount type=bind,source=/tmp/.X11-unix,target=/tmp/.X11-unix,readonly \
5. 将网络类型设置为host
在构建镜像时进行配置 podman build --network=host --tag guitest .
Containerfile
FROM debian:latest
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update && apt upgrade
RUN apt install --no-install-recommends --yes firefox-esr pipewire pipewire-alsa pipewire-pulse ffmpeg xauth
ENV PROTOCOL=MIT-MAGIC-COOKIE-1
ENV HOME /home/def
ENV USER def
RUN useradd --create-home --home-dir ${HOME} -G audio,video ${USER} && chown -R ${USER}:${USER} ${HOME}
WORKDIR ${HOME}
USER ${USER}
RUN touch .Xauthority
CMD xauth add ${HOST}:0 $PROTOCOL $KEY && firefox
构建命令
podman build --network=host --tag guitest .
使用我们构建的镜像运行容器
podman run -it --rm --name guiapp \
--env DISPLAY \
--env KEY=$(xauth list | sed '2,$d'| tr -d '\n' | tail -c 32) \
--mount type=bind,source=/tmp/.X11-unix,target=/tmp/.X11-unix,readonly \
guitest
BINGO!火狐浏览器的图形用户界面就在你眼前。
免责声明此示例中无法工作的音频,需要额外的步骤使音频正常运行。