写点什么

详解 Docker 容器运行 GUI 程序的方法

  • 2023-03-06
    广东
  • 本文字数:1463 字

    阅读完需:约 5 分钟

详解Docker容器运行GUI程序的方法

本文分享自华为云社区《Docker容器运行GUI程序的方法(直接进入Docker容器运行或通过SSH连接Docker容器运行)》,作者:MAVER1CK 。


以下两种方法都需要先在主机执行 xhost + 命令,若无该命令,先 apt 安装 x11-xserver-utils 后再执行,否则会报 No protocol specified 这个错


sudo apt install x11-xserver-utilsxhost +
复制代码

直接进入 Docker 容器运行

针对远程容器


docker-compose.yml 中需要绑定挂载 /tmp/.X11-unix


    volumes:      - "/tmp/.X11-unix:/tmp/.X11-unix:rw"    environment:      - DISPLAY=$DISPLAY      - QT_X11_NO_MITSHM=1
复制代码


若出现 X11 connection rejected because of wrong authentication. 这个错,则需要再挂载 ~/.Xauthority


    volumes:      - "/tmp/.X11-unix:/tmp/.X11-unix:rw"      - "~/.Xauthority:/root/.Xauthority:rw"    environment:      - DISPLAY=$DISPLAY      - QT_X11_NO_MITSHM=1
复制代码


这种方法有个问题:虽然将主机中的 Xauthority 文件使用绑定挂载共享到容器中,但容器中的该文件数据更新不及时(可以在主机和容器中分别使用 xauth list 命令查看详情,对比这两个文件的内容),导致即使挂载 Xauthority,也会报 X11 connection rejected because of wrong authentication. 这个错,必须重启容器才可以继续显示图像。而通过 SSH 连接容器则不会出现这个问题。举个例子:


  1. 一台 NUC 上运行了一个容器,已经使用 docker compose up -d 部署了容器,在开机脚本里写了自启容器的命令,每次 NUC 开机都会自动启动容器

  2. 使用笔记本电脑 ssh 连接到了 NUC,再在这个 ssh 连接中进入容器

  3. 在容器中运行 GUI 程序,成功显示了窗口

  4. 退出容器,并断开了与 NUC 的 ssh 连接

  5. 再次 ssh 连接 NUC,重复步骤 2. 3.,但未能显示图形,报错:X11 connection rejected because of wrong authentication.

  6. 在容器中执行 xauth list 命令,再在 NUC 中执行相同命令,可以看到设备名相同,但 cookie 值不同,导致认证失败

  7. 不断开 ssh 连接,重启容器并再次运行 GUI 程序,成功显示图形

针对本地容器


直接使用 docker exec 命令或通过下文 ssh 的方法进入容器


例如容器中使用的是 bash


docker exec -it [容器名称] bash
复制代码


然后在当前终端中输入命令执行 GUI 程序即可

通过 SSH 连接 Docker 容器运行


根据官方文档说明,在 host 网络模式下无法使用端口映射,为了使容器的 ssh 端口和主机的 ssh 端口不冲突(做到既可以连接主机,又可以连接容器),需要修改容器中默认的 ssh 端口,又因为容器中默认为 root 用户,且为随机生成密码,所以还要修改容器的 ssh 配置文件,允许以 root 身份 ssh 登陆,并修改容器 root 用户的密码,最后还要让容器每次启动的时候自动启动 ssh 服务(因为容器没有 systemd,不会自启 ssh 服务)。注意不能挂载主机的 Xauthority 文件,但要挂载 /tmp/.X11-unix


volumes:      - "/tmp/.X11-unix:/tmp/.X11-unix:rw"environment:      - DISPLAY=$DISPLAY      - QT_X11_NO_MITSHM=1
复制代码


1. 修改容器 ssh 端口并允许 root 用户登陆


vim /etc/ssh/sshd_config
复制代码


  • 将 Port 解注释,并把值从 22 改为其他值(不能使用主机正在使用的端口,因为容器在 host 模式下与主机共用端口),比如 2222

  • 然后找到 PermitRootLogin ,解注释并把值改为 yes


2. 修改 docker-compose.yml,使容器启动时自启 ssh 服务:在 command 处增加命令


service ssh start
复制代码


因为我的容器已经在启动时执行了 tail -f /dev/null 命令,因此需要下面这种写法以使容器执行多条命令


    command: bash -c "service ssh start && tail -f /dev/null"
复制代码


3. 最后通过 ssh 命令连接


ssh -p 2222 root@localhost -Y
复制代码

点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 4
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
详解Docker容器运行GUI程序的方法_开发_华为云开发者联盟_InfoQ写作社区