【GUI】本地电脑弹出远程服务器的软件GUI界面

将在远程 Docker 容器中运行的 GUI 界面显示在本地 Windows 电脑的完整教程

目标

本教程将指导您完成所有必要配置,以实现以下目标:

在您的本地 Windows 11 电脑上,通过 MobaXterm 软件,显示一个运行在远程 Ubuntu 主机的 Docker 容器内部的图形用户界面(GUI)程序。

  • 本地主机: Windows 11 (已安装 MobaXterm)
  • 远程主机: Ubuntu 24.04 (运行 Docker)
  • Docker 容器: Ubuntu 20.04
核心原理:X11 转发

整个过程的核心是利用 SSH 的 X11 转发功能。我们会建立一条安全的隧道,将 GUI 程序的"显示"信号从最深处的 Docker 容器,一步步转发出来,最终送达您本地的 Windows 电脑进行渲染。

数据流向 :
GUI 程序 (在 Docker 内) -> Docker 容器 -> 远程 Ubuntu 主机 -> SSH 加密隧道 -> 本地 Windows 电脑 (MobaXterm)


第一步:配置本地 Windows 11 电脑 (MobaXterm)

在这一步,我们确保您的电脑已经准备好接收并显示来自远程的 GUI 数据。

  1. 启动 MobaXterm X Server:

    • 打开 MobaXterm。
    • 检查主窗口右上角。您会看到一个 "X" 字样的图标。请确保它处于启动状态(通常为彩色)。如果它是灰色的,请单击它来启动 X Server。
  2. 配置 X Server 访问权限:

    • 在 MobaXterm 顶部菜单栏,点击 "Settings" -> "Configuration"。
    • 在弹出的窗口中,选择 "X11" 标签页。
    • 在 "X11 remote access" 选项中,选择 "Full"
    • 点击 "OK" 保存。MobaXterm 可能会提示您重启 X Server,请同意。

第二步:配置远程 Ubuntu 主机 (SSH 服务)

在这一步,我们配置远程主机上的 SSH 服务,允许它转发 X11 的图形请求。

  1. 使用 MobaXterm 连接到远程主机:

    • 确保您是通过 MobaXterm 的 SSH 会话连接到远程 Ubuntu 主机的。
  2. 编辑 SSH 配置文件:

    • 在远程主机的终端中,使用您熟悉的编辑器(如 nanovim)以管理员权限打开 SSH 配置文件:

      bash 复制代码
      sudo nano /etc/ssh/sshd_config
  3. 修改/确认配置项:

    • 在文件中找到以下三行,确保它们的值如下所示。如果它们被 # 注释掉了,请删除 #;如果不存在,请在文件末尾添加它们。

      复制代码
      X11Forwarding yes
      X11DisplayOffset 10
      X11UseLocalhost no
    • 关键解释 :

      • X11Forwarding yes: 开启 X11 转发功能。
      • X11UseLocalhost no: 允许 SSH 监听来自 Docker 容器的网络连接,这是在 Docker 环境下成功的关键。
  4. 重启 SSH 服务使配置生效:

    • 保存并关闭配置文件后,运行以下命令重启 SSH 服务。请注意,在 Ubuntu/Debian 系统中,服务名称是 ssh.service

      bash 复制代码
      sudo systemctl restart ssh.service
    • 您可以运行 sudo systemctl status ssh.service 来确认服务是否已成功重启并处于 active (running) 状态。

第三步:建立带 X11 转发功能的连接并验证

这是最容易出错但也是最关键的一步。您必须使用新的 SSH 配置重新建立连接。

  1. 断开并重新连接:

    • 完全关闭当前 MobaXterm 连接到远程主机的标签页。
    • 发起一个全新的 SSH 连接到您的远程主机。
  2. 验证宿主机环境 (核心检查点):

    • 新连接 的终端中,运行以下命令:

      bash 复制代码
      echo $DISPLAY
    • 期望的输出 : 您必须看到类似 localhost:10.0localhost:11.0 的输出。

    • 如果输出为空 : 说明 X11 转发通道没有建立成功。请回到第二步,仔细检查 SSHD 配置文件和重启操作,然后再次尝试本步骤。在看到正确的 DISPLAY 值之前,请不要进行下一步。

第四步:运行 Docker 容器并传入显示信息

在宿主机环境配置正确后,我们现在可以启动 Docker 容器,并把正确的"显示地址"传递给它。

  1. 准备 Docker 命令:

    • 您之前使用的 docker run 命令已经非常完善,包含了所有必要的参数。我们将继续使用它。
  2. 运行 Docker 容器:

    • 在您已经验证 echo $DISPLAY 有正确输出的那个终端里,执行以下命令。这会确保宿主机上正确的 $DISPLAY 变量值被传递到容器内部。
    bash 复制代码
    # 如果旧的容器还在运行,建议先停止并删除它,以确保应用新设置
    docker stop asw_build_env_gui
    docker rm asw_build_env_gui
    
    # 使用您原来的命令重新创建并启动容器
    docker run -it --name asw_build_env_gui \
      --shm-size="5g" \
      -u $(id -u):$(id -g) \
      --net host \
      --env DISPLAY=$DISPLAY \
      --env no_proxy="boscharena.ai,localhost,127.0.0.1,127.*" \
      --env NO_PROXY="boscharena.ai,localhost,127.0.0.1,127.*" \
      --env USER=$USER \
      -v $HOME:$HOME \
      -v /tmp/.X11-unix:/tmp/.X11-unix \
      artifactory.prod.boscharena.ai/pj_j6e_docker_local/asw_docker_base:1.4.1
  3. 进入容器后再次验证:

    • 当您进入容器的交互式 Shell 后,再次运行:

      bash 复制代码
      echo $DISPLAY
    • 期望的输出 : 此时,容器内的输出应该和您在宿主机上看到的一模一样,即 localhost:10.0 或类似值。这表明"显示地址"已成功传递。

第五步:最终测试

现在,整个转发链路已经打通。让我们运行一个 GUI 程序来验证成果。

  1. 在容器内运行一个测试程序 :
    • 如果您的容器镜像内没有预装 GUI 程序,可以安装一个简单的测试工具包 x11-apps

      bash 复制代码
      # 您可能需要 root 权限 (sudo)
      apt-get update && apt-get install -y x11-apps
    • 运行 xeyes (一双会跟随您鼠标的眼睛) 或 xclock (一个简单的时钟):

      bash 复制代码
      xeyes

如果一切顺利,xeyesxclock 的窗口现在应该会神奇地出现在您本地的 Windows 11 桌面上!


故障排查

  • 问题 : 在远程主机 echo $DISPLAY 为空。

    • 原因: SSH X11 转发未成功建立。
    • 解决方案 : 严格检查并重复第二步第三步 。确保 sshd_config 文件无误,服务已重启,并且您是重新连接的 SSH 会话。
  • 问题 : 在容器内运行 GUI 程序,提示 Error: Can't open display: localhost:10.0

    • 原因: 容器无法连接到 X11 socket。
    • 解决方案 : 检查 docker run 命令中 -v /tmp/.X11-unix:/tmp/.X11-unix 是否正确。同时,使用 --net=host 参数通常能解决这类网络问题。
  • 问题: GUI 程序弹出,但非常卡顿。

    • 原因: X11 转发对网络带宽和延迟敏感。
    • 解决方案: 确保您与远程主机之间的网络连接稳定。对于复杂的 3D 渲染等应用,X11 转发可能性能不佳,可以考虑 VNC 或 RDP 等其他方案。
相关推荐
宁&沉沦3 小时前
Nginx清除浏览器缓存的三个缓存响应头的关系详解
运维·nginx·缓存
报错小能手3 小时前
计算机网络自顶向下方法4——详解协议层次及其服务模型
服务器·计算机网络·php
hwshea3 小时前
Elasticsearch安装与配置全指南
运维·jenkins
java_logo3 小时前
Docker 部署银河麒麟(Kylin Linux)全流程教程
linux·运维·阿里云·docker·容器·kylin
莫陌尛.4 小时前
Docker安装MongoDO
运维·docker·容器
喜欢踢足球的老罗4 小时前
零依赖一键多端!用纯 Node.js 打造“IP 可访、角色隔离”的轻量化 Mock 服务器
服务器·tcp/ip·node.js
Gss7774 小时前
应用商城发布项目
运维
大头an4 小时前
一网打尽:手把手教你搭建PXE网络启动服务器
运维
阿沁QWQ4 小时前
Linux进程信号
linux·运维·服务器