使用x11转发在macos上从docker容器中启动gui程序

2024/10/06

Tags: X11 MacOS Docker GUI

Table of Contents

0.写在前面

之所以要研究这个,主要是我写的一个Yolo目标检测AI 模型的辅助训练软件label-image不支持Windows平台, 如果需要在Windows上使用, 需要在Windows上启动ubuntu的docker ,再从中启动 ubuntu版本的label-image 通过转发x11消息的方式显示,在Nvidia-docker2的加持下, 直接从docker中访问windows上的显卡,使用cuda加速模型训练

虽然目前MacOS的MPS不管是性能还是配套,都没有Nvidia CUDA做得好,不支持从docker中硬件加速,但我还是觉得有必要研究一下,毕竟将来也许也就支持了.

1.安装 XQuartz

XQuartz

为了让mac os可以作为X11服务器,接收来自linux的x11消息

安装XQuartz ,安装完后,配置为允许从网络客户端接收消息

image-20241005195115178

设置允许的x11客户端

1
xhost +  #表示不过滤任务客户端ip

2. 创建一个ubuntu docker镜像,安装中文输入法

dockfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
FROM --platform=linux/amd64 ubuntu:20.04
#FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive

COPY .gitconfig /root/.gitconfig
COPY .vimrc /root/.vimrc

RUN \
apt update && \
apt install -y  \
build-essential \
software-properties-common &&\
apt update && \
apt install -y locales language-pack-zh-hans language-pack-gnome-zh-hans fonts-wqy-zenhei fonts-wqy-microhei ibus-rime librime-data-wubi && sed -i.bak 's/# zh_CN.UTF-8/zh_CN.UTF-8/g' /etc/locale.gen && locale-gen && update-locale LANG=zh_CN.UTF-8 && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
apt install -y \
  autoconf \
  gnome \
  automake \
  bison \
  build-essential \
  cmake \
  gcc \
  g++ \
  git \
  lsb-release \
  make \
  ninja-build \
  python3 \
  rsync \
  tar \
  unzip \
  vim \
  wget \
  curl \
  cowsay && \
  apt install -y openssh-server && echo 'root:aaa' | chpasswd && sed -i.bak 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config && service ssh restart  && \
  apt clean && \
  mkdir -p /opt/label-image

#COPY .config /root/.config

WORKDIR  /opt/label-image
ENTRYPOINT ["/bin/bash","-c" ,"service ssh start && tail -f /dev/null"]

第14行,设置时区,本地化,安装字体,输入法等

第36行设置open ssh 服务,支持以root用户远程登录

第40行,复制输入法相关的配置,.config 文件夹是在配置好输入法后复制出来的文件夹,可选

build docker的指令

1
docker build . -f dockfile -t repos:version

3.启动docker container

创建一个 脚本来启动docker 容器 runDocker.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash


display=${HOSTNAME}:0
runcmd="docker run \
--name  hbb
--privileged \
--device /dev/mem \
-p 2246:22 \
-e DISPLAY=$display \
-e LANG=zh_CN.UTF-8 \
-e XMODIFIERS=\"@im=ibus\" \
-e QT_IM_MODULE=\"ibus\" \
-e GTK_IM_MODULE=\"ibus\" \
-e GID=`id -g` \
-e UID=`id -u` \
-v /tmp/.X11-unix/:/tmp/.X11-unix  \
--entrypoint /bin/bash \
--rm
-it label-image:u2004 -c 'ibus-daemon -xrd && gedit'"

eval $runcmd

与输入法相关的,除了几个环境变量外,还需要挂载/tmp/.X11-unix 以转发x11消息

脚本入口点为/bin/bash, 参数为 -c ibus-daemon -xrd && gedit 表示先启动输入法的守护进程,再打开gedit文本编辑器

然后脚本权限后 运行脚本

1
2
sudo chmod +x runDocker.sh
./runDocker.sh

这时会看到启动了一个dockr,并以交互的方式打开了容器中的gedit

如果在步骤2中没有第40行,这时是无法使用输入法的,

可以重新开一个终端进入docker中

1
docker exec -it  hbb  bash  #hbb是步骤3脚本中--name 参数指定的
1
ibus-setup #弹出Ibus输入法配置窗口

设置好输入法后,把 ~/.config/dconf ~/.config/ibus 复制出来, 补充到步骤2的第40行处,

重新执行一下docker build,这时会很快速的基于上一次缓存的结果再生成一个带有输入法配置的docker image

4.附录

4.1设置ibus默认输入法的方法

我没有找到从命令行配置输入法的方法, (否则就能直接在run脚本中配置)

所以我的方式是,先启动命令行,在里面配置好输入法,再把相关的配置以文件的方式保存,

再做一个docker image把配置文件覆盖进去,或挂载去去

ubuntu与ibus配置相关的配置在 ~/.config/dconf

ibus-rime的配置文件在 ~/.config/.config/ibus

在步骤3中启动的docker中,配置ibus-rime为输入法

1
ibus-setup

这时会转发x11到mac os的x11 server上, 弹出配置窗口

image-20241005201244120

添加rime输入法, 最好也设置一下自己喜欢的切换输入法的快捷键,不要和mac os冲突了.

然后修改~/.config/ibus/rime 里的配置, 这个因人而异,我就此略过

都做好修改后,把~/.config/dconf和~/.config/ibus 文件备份出来,如果对命令行复制不熟悉,可以使用fileZilla之类的支持sftp或scp的图形化工具, 在步骤2中已经把host的2246u端口转发到docker container中了,

再做一个docker, 在步骤2中前几行,把备份的文件覆盖进去新的镜像中,即可

4.2 x11 消息转发显示的 GUI程序+输入法 效果

image-20241005204027682

>> Home

Comments