实现类似Manus在浏览器显示远程桌面的功能

204 阅读6分钟

实现类似Manus在浏览器显示远程桌面的功能

image.png

看到了Manus的demo,感觉可以显示远程控制浏览器的页面感觉很炫酷,想探索是如何能实现这个功能。正好今天Manus也开放使用了。

🔍 探索的第一步:了解 VNC 与 noVNC

要实现在浏览器中显示远程桌面,首先要理解 VNC(Virtual Network Computing) 是什么。简单来说,它是一种远程控制协议,允许你在一台机器上查看并操作另一台机器的桌面界面。

传统的 VNC 需要安装客户端软件,比如 RealVNC 或 TightVNC。但如果你希望把这套体验搬到浏览器中呢?

这就轮到 noVNC 上场了。noVNC 是一个纯 HTML5/JavaScript 实现的 VNC 客户端,它可以:

  • 直接运行在现代浏览器中
  • 支持 WebSocket 通信
  • 使用 Canvas 渲染远程桌面画面
  • 完全不需要额外插件或客户端

换句话说,noVNC 把原来需要安装客户端的 VNC 过程,变成了一个可以在浏览器中打开的网页应用。

🧩 搭建思路:我们需要哪些组件?

为了模拟 Manus 的演示效果,我构建了一个包含以下核心组件的环境:

Xvfb :虚拟屏幕服务器,在无显示器的环境中创建一个图形界面 Firefox :在虚拟屏幕上运行的真实浏览器 X11VNC :将虚拟桌面内容作为 VNC 服务暴露出来 noVNC :提供基于浏览器的 VNC 客户端访问入口 Flask API :对外提供 RESTful 接口,用于控制浏览器行为 Docker + Supervisor :用于打包部署整个系统,统一管理多个进程 这些组件协同工作,最终实现了这样一个流程:

用户通过浏览器访问 noVNC 页面 → 连接到远程桌面 → 看到 Firefox 正在自动访问某个网页 → 同时可通过 API 控制其行为(如滚动、跳转等)

那么接下来就是具体写代码了,动手干活

这里为了方便部署,我使用了docker容器的方式 非常好的 Dockerfile!它构建了一个完整的远程浏览器控制环境,整合了图形界面、VNC、noVNC 和 Python API 控制层。你希望在技术文章中讲解这个 Dockerfile,但又不希望“太幼稚太简单”,所以我们来设计一个进阶式、结构清晰、有深度的技术讲解方式


🧩 一、整体架构概览

这个 Dockerfile 构建的是一个 基于 Ubuntu 的容器化远程浏览器运行环境,其核心目标是:

在无物理显示设备的环境下运行 Firefox 浏览器,并通过 WebSocket + noVNC 实时展示其桌面画面,同时提供 RESTful 接口用于远程控制浏览器行为。

整个系统由以下几部分组成:

组件作用
Xvfb虚拟 X 显示服务器,模拟显示器
XFCE4轻量级桌面环境,在虚拟显示器上运行
X11VNC将虚拟桌面内容以 VNC 协议暴露出去
noVNC基于 Web 的 VNC 客户端,可在浏览器中访问
Firefox运行在虚拟桌面中的真实浏览器
Flask API提供 REST 接口用于控制浏览器行为
Supervisor管理多个服务进程

🔧 二、Dockerfile 模块化解析

1. 基础配置与环境准备

FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
ENV DISPLAY=:1
  • 使用官方 Ubuntu 22.04 镜像作为基础。
  • 设置 DEBIAN_FRONTEND=noninteractive 避免交互提示(适用于自动化部署)。
  • 设置默认显示变量 DISPLAY=:1,表示使用 X server 编号为 1 的虚拟屏幕。
RUN apt-get update && apt-get install -y software-properties-common ...

安装常用工具链和依赖项,包括图形支持库、字体、DBus 支持等,确保 Firefox 可以正常运行。


2. 安装 Firefox(从 PPA)

RUN add-apt-repository ppa:mozillateam/ppa -y
RUN echo 'Package: firefox*\nPin: release o=LP-PPA-mozillateam\nPin-Priority: 1001' > /etc/apt/preferences.d/mozilla-firefox

这里使用了 Mozilla 官方 PPA 并设置了优先级,确保安装的是最新版 Firefox 而非 Ubuntu 自带的旧版本。

Firefox 对远程自动化的兼容性较好,适合用作浏览器控制的核心组件。


3. 安装 VNC 相关组件

RUN apt-get install -y x11vnc novnc supervisor
  • x11vnc: 将 X11 显示内容转换为 VNC 协议输出
  • novnc: 提供基于浏览器的 VNC 客户端,通过 WebSocket + Canvas 实现远程桌面访问
  • supervisor: 多服务管理工具,用于统一启动并守护多个后台进程

4. 安装 geckodriver(Selenium WebDriver)

RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux64.tar.gz \
    && tar -xvzf geckodriver-v0.33.0-linux64.tar.gz \
    && mv geckodriver /usr/local/bin/

geckodriver 是 Selenium 控制 Firefox 所必需的中间件。它实现了 W3C WebDriver 标准协议,让程序可以通过 HTTP 请求与浏览器交互。


5. 设置 VNC 密码

RUN mkdir -p /root/.vnc && \
    x11vnc -storepasswd "password" /root/.vnc/passwd

设置默认 VNC 登录密码为 password,方便测试连接。生产环境中应改为动态或随机生成。


6. 安装 Python 依赖并复制代码

COPY browser-control-api.py /app/
COPY requirements.txt /app/
RUN pip3 install --no-cache-dir -r requirements.txt

这部分将本地的 Flask API 服务代码打包进容器,并安装所需的 Python 包(如 Flask、selenium、subprocess 等)。


7. 创建启动脚本

RUN echo '#!/bin/bash\necho "Firefox服务启动,等待API指令..."\nsleep infinity' > /app/start-firefox.sh

这是一个简单的占位脚本,用于启动 Firefox 并保持运行状态。实际运行中可替换为真正启动浏览器的命令,或结合 selenium 启动 headless 或可见模式。


8. 配置 Supervisor 管理多服务

[program:xvfb]...
[program:xfce]...
[program:x11vnc]...
[program:novnc]...
[program:flask]...

Supervisor 配置非常关键,它确保以下服务按顺序启动并保持运行:

  • Xvfb:创建虚拟显示
  • XFCE:提供桌面环境
  • X11VNC:将虚拟桌面转为 VNC 输出
  • noVNC:提供 Web VNC 访问入口
  • Firefox:浏览器主进程
  • Flask:RESTful API 服务

9. 中文支持与字体配置

RUN locale-gen zh_CN.UTF-8 && \
    update-locale LANG=zh_CN.UTF-8 LANGUAGE=zh_CN:zh LC_ALL=zh_CN.UTF-8

RUN apt-get install -y fonts-noto-cjk fonts-wqy-microhei fonts-wqy-zenhei

这部分确保中文网页可以正确渲染,避免乱码或字体缺失问题。


10. Firefox 首选项配置

echo 'user_pref("intl.accept_languages", "zh-CN,zh,en-US,en");'

设置 Firefox 默认语言为中文,提高浏览器在中文环境下的兼容性和易读性。


三、容器启动后的行为说明

当容器启动后,会依次执行以下操作:

  1. 启动 Xvfb,创建一个分辨率为 1920x1080 的虚拟显示
  2. 启动 XFCE 桌面环境,为 Firefox 提供运行环境
  3. 启动 X11VNC,将虚拟桌面通过 RFB 协议发布到 5900 端口
  4. 启动 noVNC,监听 6080 端口,提供基于浏览器的 VNC 客户端
  5. 启动 Flask API,监听 5000 端口,提供远程控制接口
  6. 启动 Firefox,等待 API 发送 URL 或其他控制命令

📌 四、使用方法

  1. 访问 http://localhost:6080/vnc.html 查看远程桌面
  2. 使用 VNC 密码 password 登录
  3. 通过 API 控制浏览器打开页面:
    curl -X GET http://localhost:5000/scroll?url=bilibili.com&duration=60&interval=1.5
    

本项目提供了一个简单的前端控制面板 index.html,你可以直接打开使用

image.png

Github代码地址

📌 项目源码已开源,欢迎尝试 github.com/varrff/novn…