news 2026/8/20 1:07:43

使用 Docker 部署 DotNetBrowser 应用程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 Docker 部署 DotNetBrowser 应用程序

DotNetBrowser 是一个基于 Chromium 的 .NET WebView。它允许您在 .NET 桌面应用中嵌入现代网页内容,并通过代码对其进行控制。

与普通的 .NET 应用不同,运行 Chromium 的应用依赖一些系统级组件,这些组件并不包含在您的项目中。应用可能在您的电脑上运行良好,但在一个干净的服务器或 CI 环境中却无法运行。

Docker 通过将应用程序与其所需的完整运行环境一起打包来解决这个问题。本文将介绍如何使用 Docker 部署 DotNetBrowser 应用。

为什么选择 Docker

DotNetBrowser 构建于 Chromium 之上,这意味着它继承了 Chromium 的系统要求。在 Linux 上,这包括原生库和用于渲染内容的 X 服务器。在典型的桌面设置中,这些部分已经由操作系统提供。但在 CI 或服务器环境中,它们通常是缺失的。

Docker 允许您显式地定义和打包环境。这使您的应用程序更具可预测性,并减少了经典的“在我机器上能跑”的问题。当您需要在官方支持列表之外的 Linux 发行版上运行时,它也能派上用场。

准备工作

我们将构建一个小型的 .NET 应用程序,并使用 Docker 进行打包。要跟着操作,您需要:

  • Docker Engine。
  • .NET 8 SDK。
  • DotNetBrowser 许可证。

创建 DotNetBrowser 应用

对于本例,我们将使用以下项目结构:

Example.Docker/ ├── <App files> # 应用程序源文件 ├── Dockerfile # Docker 构建文件 └── startup.sh # 用于启动应用的脚本

让我们从创建一个简单的 Avalonia 桌面应用开始。为了简化操作,我们将使用官方的 DotNetBrowser Avalonia 模板,而不是从头开始设置一切。

首先,安装模板:

dotnet newinstallDotNetBrowser.Templates

然后创建一个新项目:

dotnet new dotnetbrowser.avalonia.app-oExample.Docker-li<your_license_key>

这将在Example.Docker文件夹中生成一个可立即运行的 Avalonia 应用程序。开箱即用,它会打开一个窗口并在 DotNetBrowser 中加载一个网页。

由于应用将在 Docker 容器中运行,我们需要一种方式来确认它在没有可见窗口时也能正常运行。可以在页面加载完成后将网页标题打印到控制台。

MainWindow.axaml.cs中添加代码:

// 页面加载完成后打印标题。browser.Navigation.FrameLoadFinished+=(_,e)=>{if(e.Frame.IsMain){Console.WriteLine($"Title:{browser.Title}");}};// 加载网页。browser.Navigation.LoadUrl("https://www.google.com");

完成此操作后,应用程序就可以打包了。下一步是生成 Release 构建:

dotnet publish-cRelease-oout

生成的out/目录将在运行时被容器使用。

创建 Dockerfile

现在,我们需要定义应用程序运行的环境。在 Docker 中,这是通过Dockerfile完成的。

我们的目标是构建一个包含以下内容的镜像:

  • .NET 运行时
  • Chromium 的 Linux 原生依赖项
  • 一个虚拟显示服务器
  • 已发布的应用程序文件

让我们一步步构建它。

基础环境配置

以基础镜像开始您的Dockerfile

FROM mcr.microsoft.com/dotnet/runtime:8.0

此镜像基于 Debian,并且已经包含了 .NET 运行时,因此无需手动安装。

请记住,Chromium 依赖于glibc。因此,您不能使用 Alpine 或任何其他依赖于musl或其他标准 C 库的 Linux 发行版。

接下来,为安装软件包设置一个非交互式环境:

ENV DEBIAN_FRONTEND=noninteractive

这可以确保apt-get在安装过程中不会暂停并等待输入。

安装 Chromium 依赖项

Chromium 依赖于几个原生 Linux 库。它们负责处理窗口、图形、声音和安全性等基本系统功能。在最小的 Docker 镜像中,这些库默认不会安装。

RUN apt-get update && \ apt-get -y install --no-install-recommends \ libgtk2.0-0 \ libgtk-3-0 \ libgbm1 \ libnotify4 \ libgconf-2-4 \ libnss3 \ libxss1 \ libasound2 \ libxtst6 \ xauth \ xvfb \ x11-xserver-utils && \ rm -rf /var/lib/apt/lists/*

我们还安装了Xvfb,一个轻量级的虚拟 X 服务器。它允许 DotNetBrowser 在没有物理显示器可用时运行。

添加应用程序

现在环境已准备就绪,我们可以添加应用程序了。我们需要定义它的启动方式并将其文件复制到容器中。

  1. 创建启动脚本。

我们不直接启动应用程序,而是使用一个小的包装脚本:

#!/bin/shset-eif[-z"${DISPLAY:-}"];thenXvfb :0-screen01920x1080x24&exportDISPLAY=:0fiexecdotnet Example.Docker.dll

此脚本通过DISPLAY变量检查是否有 X 服务器可用:

  • 如果未设置DISPLAY,它会启动一个虚拟显示器,并将应用程序指向它。
  • 如果设置了DISPLAY,则假定有真实的 X 服务器可用并正常运行。

即使显示器是虚拟的,Chromium 也会像对待真实屏幕一样对待它。所以我们使用-screen选项设置分辨率和色深。

  1. 将脚本复制到镜像中:
WORKDIR /Example.Docker COPY startup.sh . RUN chmod +x startup.sh

我们设置一个工作目录,复制脚本,并使其可执行。

  1. 复制先前发布的应用程序文件:
COPY out/ .
  1. 定义入口点:
ENTRYPOINT ["/Example.Docker/startup.sh"]

这告诉 Docker 在容器启动时执行什么。

至此,Docker 镜像已准备就绪。下一步是构建它并观察其运行。

构建并运行容器

确保 Docker Engine 正在运行,然后构建镜像:

dockerbuild-tdnb-app-fDockerfile.

运行容器通常有两种方式:

  • 无头模式— 适用于自动化、测试和服务器端运行,不需要用户界面。
  • 桌面模式— 适用于希望查看应用程序窗口并进行可视化调试的场景。

以下是每种模式的工作原理。

无头模式

无头模式是 CI 或服务器环境中最常见的设置。在这种模式下,应用程序使用虚拟 X 服务器运行,而不是真实的显示器。

运行容器:

dockerrun--rm--shm-size=1g dnb-app

由于没有设置DISPLAY,启动脚本会启动 Xvfb 并在无头模式下运行应用程序。

--shm-size=1g选项增加了分配给容器的共享内存量。Chromium 使用共享内存在其进程之间进行通信。在大多数 Linux 系统上,默认情况下共享内存足够大。但在 Docker 中,它被限制为 64 MB —— 对于 Chromium 来说太小了。

在示例应用程序中,我们加载 Google 并打印页面标题。当容器启动时,您应该看到:

Title: Google

桌面模式

桌面模式适用于您希望看到容器内的应用程序窗口的情况——例如,调试渲染问题或测试用户输入。在这种情况下,容器需要访问您主机的 X 服务器。

这种方法适用于使用 X11 的 Linux 系统。在 Linux 上,图形应用程序通过 Unix 套接字与 X 服务器通信,DISPLAY变量告诉它们使用哪个显示器。我们将此信息传递给容器,以便应用程序能够在您的主机桌面上显示其窗口。

首先,允许本地连接到您的 X 服务器:

xhost +local:root

然后启动容器:

dockerrun--rm\--shm-size=1g\-eDISPLAY=$DISPLAY\-v/tmp/.X11-unix:/tmp/.X11-unix\dnb-app

这里发生了什么:

  • -e DISPLAY=$DISPLAY告诉应用程序要使用哪个显示器。
  • -v /tmp/.X11-unix:/tmp/.X11-unix挂载了 X11 通信套接字。

应用程序窗口应该会出现:

由容器渲染的应用程序窗口。

完成后,您可以撤销 X 服务器的权限:

xhost-local:root

完整的示例应用程序可在 GitHub 仓库 中找到。

远程调试

当出现问题时,您需要查看 Chromium 内部发生了什么——检查 DOM、调试 JavaScript 或监控网络请求。

在 DotNetBrowser 中,通过引擎选项启用远程调试:设置端口并添加--remote-allow-origins开关。

将以下配置添加到EngineOptions.Builder中:

IEngineengine=EngineFactory.Create(newEngineOptions.Builder{ChromiumSwitches={"--remote-allow-origins=http://localhost:9222"},RemoteDebuggingPort=9222}.Build());

修改应用程序后,不要忘记重新构建 Docker 镜像。

当 Chromium 在容器内运行时,DevTools 无法直接从您的主机访问。Chromium 在本地端口上暴露 DevTools ——但这里的“本地”指的是容器内部。要从主机访问 DevTools,请使用 SSH 本地端口转发。

在主机上,启动容器并发布 SSH 端口:

dockerrun-d-p2222:22 --shm-size=1g dnb-app

在正在运行的容器内打开一个 shell:

dockerexec-it<container_id>/bin/bash

<container_id>替换为正在运行的容器的 ID。您可以通过运行docker ps找到它。

在容器内部安装并启动 SSH 服务器:

aptinstall-yopenssh-serverservicesshstart

在容器内部,创建一个用于 SSH 访问的用户:

useradd--create-home--shell/bin/bash dnb-apppasswddnb-app

在主机上,转发远程调试端口:

ssh-L9222:localhost:9222-p2222dnb-app@localhost

此命令创建了一个从主机的localhost:9222到容器内部的localhost:9222的隧道。在使用 DevTools 期间,请保持此 SSH 会话打开。

在主机上,打开 Google Chrome 并加载chrome://inspect以访问 DevTools。

总结

DotNetBrowser 应用程序不仅仅是一个 .NET 进程——它嵌入了一个完整的 Chromium Engine。该 Engine 期望特定的系统库和一个显示服务器。Docker 允许您显式定义该环境,并在本地、CI 或生产环境中运行相同的镜像,获得一致的结果。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 16:26:06

Python IDE配置lumapi

1. 参考这篇Lumerical Python API配置-一步到位-CSDN博客 注意第二行是你的解释器&#xff08;python&anaconda&#xff09;的\python目录下的DLLs文件 具体示例如下&#xff1a;以vscode的python解释器为例 测试代码如下&#xff0c;如果可以成功运行并打开lumerical即可…

作者头像 李华
网站建设 2026/7/14 16:26:06

学长亲荐!降AI率软件 千笔·专业降AIGC智能体 VS PaperRed,本科生专属

在AI技术快速发展的今天&#xff0c;越来越多的本科生开始借助AI工具辅助论文写作&#xff0c;以提升效率、优化内容。然而&#xff0c;随着学术审查标准日益严格&#xff0c;AI生成内容的痕迹越来越容易被识别&#xff0c;导致论文AI率超标成为不少学生面临的“隐形危机”。面…

作者头像 李华
网站建设 2026/8/20 1:06:55

LangChain:定义智能体时代新框架

伴随模型能力跃迁&#xff0c;简单封装 AI 的时代结束&#xff0c;软件基础设施层正被重写。刚获 1.25 亿美元融资的 LangChain 是浪潮定义者之一&#xff0c;其创始人深入解析智能体底层逻辑。 智能体发展新趋势 AI 应用从“单次生成”迈向“持续执行”&#xff0c;下一代软件…

作者头像 李华
网站建设 2026/7/14 16:26:19

第T8周:猫狗识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 实验环境 python 3.9.2 tensorflow 2.10.0 Jupyter Notebook: 7.4.5代码实现 设置gpu import tensorflow as tfgpus tf.confi…

作者头像 李华
网站建设 2026/7/14 16:26:18

Flutter 三方库 iso_duration 的鸿蒙化适配指南 - 掌控 ISO 8601 持续时间标准、精准解析时间增量、构建鸿蒙跨端时间交互的基石

欢迎加入开源鸿蒙跨平台社区&#xff1a;https://openharmonycrossplatform.csdn.net Flutter 三方库 iso_duration 的鸿蒙化适配指南 - 掌控 ISO 8601 持续时间标准、精准解析时间增量、构建鸿蒙跨端时间交互的基石 在日常的鸿蒙&#xff08;OpenHarmony&#xff09;应用开发…

作者头像 李华