返回博客

如何在 Docker 中运行 Puppeteer,而不将 Chrome 随应用一起运输

Michael Lee
Michael Lee

Expert Network Defense Engineer

20-Aug-2026

TL;DR:

  • Puppeteer Docker 部署失败,当 Node 包、Chrome 可执行文件和 Linux 运行时被视为一个不可见的依赖时。 明确每个边界。
  • 官方镜像是最快的完整基线。 它将 Puppeteer、Chrome for Testing 和所需的库打包在一个已知的发布标签下。
  • 系统 Chrome 镜像让你控制操作系统,但使得 Chrome 的安装和兼容性成为你的责任。 钉住两个方面,并在构建过程中运行启动烟雾检查。
  • puppeteer-core 包含客户端,而无需下载 Chrome。 当应用程序镜像应该保持无浏览器时,将其与单独运行的浏览器配对。
  • Scrapeless Scraping Browser 让应用容器连接到管理的云浏览器。 Chrome 生命周期、浏览器依赖和浏览器出局离开 Node.js 镜像。
  • 可以免费开始。 新的 Scrapeless 账户包括免费的 Scraping Browser 运行时 - 在 app.scrapeless.com 注册。

引言:Puppeteer 需要浏览器合同

npm install puppeteer 并不是整个部署。Puppeteer 还需要一个兼容的 Chrome 可执行文件、Linux 共享库、字体、一个可写的配置文件目录、足够的内存,以及一个能够干净关闭子进程的进程模型。

Docker 只有在将这些依赖写下来时才能使其可复现。官方镜像为你写下它们。自定义镜像将合同移入你的 Dockerfile。远程浏览器设计将合同保持在应用程序镜像之外,并将 puppeteer-core 保留为客户端。

本指南使用 Puppeteer Core 25.8.0 和 Scrapeless SDK 1.11.0,两者在验证期间安装。该本地包启动了一个在其 npm 包之外提供的 Chrome 可执行文件,并返回了预期的页面标题。

为什么 Puppeteer 需要超过 npm install 的东西在 Docker 中

Puppeteer 和 Puppeteer Core 解决了不同的打包问题。

浏览器下载 预期用途
puppeteer 在安装过程中管理一个兼容的 Chrome for Testing 随捆浏览器的本地或容器启动
puppeteer-core 不下载浏览器 连接到现有的可执行文件或远程浏览器端点

包选择不配置 PID 1、共享内存、浏览器沙盒、字体、证书或容器资源限制。这些仍然是部署的责任。

前提条件

  • 应用容器的 Node.js 20。
  • 官方镜像和系统 Chrome 模式的 Docker。
  • 浏览器无依赖应用模式的 Puppeteer Core 25.8.0
  • 用于管理云浏览器的 Scrapeless 账户和 API 密钥。
  • 一个公共或明确授权的目标。

注意:在验证环境中,Docker 不可用,因此镜像构建和 docker run 命令被标记为前提缺口。Puppeteer Core 25.8.0 已安装并针对包外的 Chrome 可执行文件启动;Scrapeless SDK 加载并暴露了其 Puppeteer 连接功能,但没有可用于云会话的密钥。

选项 1 — 从官方 Puppeteer 镜像开始

官方镜像包括 Chrome for Testing、其系统依赖和匹配的 Puppeteer 版本。Puppeteer Docker 指南 文档记录了该镜像及其沙箱取向的运行要求。

固定该镜像,而不是使用 latest

dockerfile Copy
FROM ghcr.io/puppeteer/puppeteer:25.8.0

WORKDIR /home/pptruser/app
COPY --chown=pptruser:pptruser package.json package-lock.json ./
RUN npm ci
COPY --chown=pptruser:pptruser . .

CMD ["node", "capture.mjs"]

文档中的镜像在其沙箱中运行 Chrome,因此容器运行时必须提供所需的能力。它还需要一个 init 进程来管理浏览器子进程:

bash Copy
docker build -t puppeteer-job:25.8.0 .
docker run --rm --init --cap-add=SYS_ADMIN puppeteer-job:25.8.0

在审查工作负载和运行时后,仅授予能力。NIST 容器安全指导 将镜像风险、注册表风险、编排器控制、运行时控制和主机控制分开。

选项 2 — 自己安装系统 Chrome

当组织已经管理一个浏览器库、证书链、字体或基础镜像时,自定义的系统 Chrome 镜像是合适的。

应用程序必须将 Puppeteer Core 指向已安装的可执行文件:

javascript Copy
import puppeteer from "puppeteer-core";

const browser = await puppeteer.launch({
  executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,
  headless: true,
});

const page = await browser.newPage();
await page.setContent("<title>Chrome outside the npm package</title>");
console.log(await page.title());
await browser.close();

执行验证使用了一个外部 Chrome 可执行文件,并打印出 Chrome outside the npm package。这确认 puppeteer-core 无需运输它控制的浏览器。

你的 Dockerfile 现在拥有 Chrome 的安装和兼容性。钉住浏览器包,在镜像构建期间断言其版本,并在发布镜像之前运行启动脚本。

五个容器失败需单独诊断

当错误映射到一个边界时,Puppeteer 容器失败变得更易于解决。

失败 检查证据 修正
可执行文件缺失 executablePath 和镜像包列表 安装 Chrome 或连接到远程浏览器
缺少共享库 浏览器标准错误和链接库检查 添加特定操作系统依赖项
沙箱启动错误 用户、内核策略和容器能力 恢复受支持的非根沙箱合同
渲染器在负载下关闭 内存、IPC 和 /dev/shm 配置 设置显式容器资源和共享内存
子进程保持 PID 1 和关闭信号处理 使用 --init 并在 finally 中关闭浏览器

Linux 名称空间隔离进程视图、挂载、用户和网络资源。Linux 名称空间手册 描述了这些隔离原语。浏览器沙箱和容器边界互为补充;一个并不替代另一个。

开始使用 Scrapeless 抓取

使用 Scrapeless 提升您的网络抓取和自动化工作流程!
今天注册并获得 5 美元的免费积分——无需信用卡

现在在 Scrapeless 仪表板 领取您的免费积分。
Scrapeless 仪表板显示 5.00 美元的团队积分

将 Chrome 移出应用程序容器

无浏览器的应用程序映像安装 puppeteer-core,打开远程浏览器会话,执行批准的页面工作,并关闭连接。浏览器服务独立扩展和升级。

安装验证项目中使用的确切软件包:

bash Copy
npm install puppeteer-core@25.8.0 @scrapeless-ai/sdk@1.11.0

注意:以下连接需要您的 Scrapeless API 密钥。已安装的 SDK 导出已在本地检查,但无凭证环境无法打开云浏览器。

javascript Copy
import { Puppeteer } from "@scrapeless-ai/sdk";

const browser = await Puppeteer.connect({
  sessionName: "browser-free-app",
  sessionTTL: 300,
  proxyCountry: "US",
  defaultViewport: null,
});

const page = await browser.newPage();
await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
console.log(await page.title());
await browser.close();

Scrapeless 抓取浏览器是该模式中的浏览器层。请查看 抓取浏览器快速入门产品页面定价,然后再在 CI 中采用它。

围绕远程边界构建应用程序

应用程序容器不再需要在同一个 Compose 项目中有 Chrome 服务。它只需要 Node.js 代码、其锁定文件、Puppeteer Core 客户端和在运行时提供的密钥。

yaml Copy
services:
  worker:
    build: .
    init: true
    environment:
      SCRAPELESS_API_KEY: ${SCRAPELESS_API_KEY}
    read_only: true
    tmpfs:
      - /tmp:size=64m

此 Compose 文件表达的是应用程序边界,而不是云浏览器。API 密钥来自于部署密钥存储。工作节点拥有只读的根文件系统和受限的临时目录。

开放容器倡议运行时配置 定义了进程、环境、挂载和 Linux 资源,这些都由运行时转换为容器进程。

选择正确的模式

当完整且匹配的 Puppeteer 和 Chrome 组件比小型映像更有价值时,请使用官方映像。当您的平台团队已经拥有浏览器发行版和操作系统策略时,请安装系统 Chrome。当应用程序不应打包或操作 Chrome 时,请使用 Puppeteer Core 和 Scrapeless 抓取浏览器。

决策可能因工作而异。用于内部模板的 PDF 渲染可能保持在固定的本地映像中。需要区域浏览器出口的公共网页提取可能属于托管云浏览器。确保二者均位于相同任务合同下,以便调用者不依赖于浏览器位置。

Scrapeless 云浏览器 Puppeteer 示例 展示了更广泛自动化工作流程中的受管理连接。

操作检查清单

  • 固定 Puppeteer、Chrome、基础映像和锁定文件版本。
  • 在发布映像之前进行浏览器启动和标题断言。
  • 使用初始化进程并在 finally 中关闭浏览器会话。
  • 为不受信任的页面保留浏览器沙箱。
  • 明确设置 CPU、内存、IPC 和临时存储限制。
  • 将 API 密钥放入运行时密钥存储中,绝不要放入映像层中。
  • 每个目标主机最多保持三个并发工作节点,除非所有者批准其他限制。
  • 记录软件包、浏览器、映像、区域和作业修订与输出。

结论:将客户端与 Chrome 解耦

当客户端包和浏览器运行时是分开且可见的决策时,Puppeteer 的操作变得更容易。官方镜像将它们捆绑在一起。自定义镜像让您的团队同时掌控这两者。Puppeteer Core 和 Scrapeless Scraping Browser 在一个受管连接中将它们分开。

为每种作业类型选择一个合同,固定它,并在应用工作负载开始之前测试浏览器边界。


准备在应用镜像中无 Chrome 运行 Puppeteer 吗?

加入我们的社区以领取免费计划,并与开发者联系,分离浏览器工作负载与 Node.js 服务:Discord · Telegram

app.scrapeless.com 注册以获得免费的 Scraping Browser 运行时并测试无浏览器的工作模式。


常见问题解答

问:Puppeteer Core 包含 Chrome 吗?

Puppeteer Core 不下载或管理 Chrome。它需要一个明确的可执行路径或远程浏览器连接。

问:官方 Puppeteer 镜像是否比自定义镜像更安全?

官方镜像提供了记录的浏览器和依赖项基准,但安全性仍然取决于镜像来源、运行时能力、用户身份、沙盒政策、主机控制和所打开的页面。

问:为什么 Chrome 仅在 Docker 内部失败?

容器可能缺少可执行文件、链接库、沙盒支持、共享内存、字体或适当的初始化进程。检查失败的边界,而不是先更改导航代码。

问:远程 Puppeteer 浏览器需要代理吗?

远程浏览器需要与作业匹配的出网政策。Scrapeless Scraping Browser 支持 195 个国家的住宅代理;固定经过批准的国家以保持一致的运行。

问:当选择器改变时应该发生什么?

重新检查渲染的页面,并根据稳定的角色、属性或数据结构更新选择器。将 Chrome 移出 Docker 不会冻结目标 DOM。

问:Puppeteer 工作者应该使用多少并发?

每个目标主机最多保持三个工作者,除非所有者批准其他限制。浏览器集群容量和目标主机的并发是独立的控制。

问:Puppeteer Core 可以在没有 AI 代理的情况下连接吗?

可以。Puppeteer Core 和 Scrapeless SDK 是直接的 Node.js 接口。AI 代理是可选的,不应改变访问、并发或秘密处理规则。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录