NextPDF Artisan 的 Chrome renderer(渲染器)配置
这个 bridge 会通过 chrome-php/chrome 启动并驱动本机 Chrome/Chromium 进程。本页将说明如何准备这套运行环境,确保渲染可以成功,并介绍容器与 sandbox 之间的取舍。
bridge 如何与 Chrome 通信
标题为“bridge 如何与 Chrome 通信”的章节BrowserPool 会构造一个 chrome-php/chromeBrowserFactory(可选择指定明确的可执行文件路径),并使用一组固定标志启动 Chrome:headless: true、keepAlive: true、windowSize: [1200, 800]、sendSyncDefaultTimeout: renderTimeout * 1000,以及 /integrations/artisan/configuration/ 页面列出的自定义标志。随后 bridge 会通过 Chrome DevTools Protocol 驱动这个已启动的进程。它不会通过远程调试端口连接到另一个独立运行的 Chrome,因此没有需要对外开放或验证的网络 endpoint。Chrome 会作为 PHP worker 的子进程运行。测试 tests/Unit/Artisan/BrowserPoolTest.php::getBrowserCreatesAndReusesInstanceWithExpectedOptions 会精确断言这些启动选项。
备妥可执行文件
标题为“备妥可执行文件”的章节安装一个 worker 用户可以运行的 Chrome 或 Chromium 版本:
# Debian / Ubuntuapt-get install -y chromium
# RHEL / Fedoradnf install -y chromium
# Alpine (containers)apk add --no-cache chromium nss freetype harfbuzz ttf-freefont以 worker 用户身份确认它可以在 headless 模式下运行:
chromium --headless --dump-dom about:blank退出代码为 0 且 DOM 为空,表示可执行文件及其依赖的共享库都已就绪。非零退出代码对应的就是 bridge 会以 ChromeRenderException 呈现的同类失败。请先在这里修复问题。
让 bridge 指向可执行文件
标题为“让 bridge 指向可执行文件”的章节当可执行文件位于标准路径时,自动检测(chrome-php/chrome 的默认行为)即可正常工作。为了让生产环境更可预测,请显式指定它:
$config = new ChromeRendererConfig( chromeBinaryPath: '/usr/bin/chromium',);或通过数组配置指定:
$config = ChromeRendererConfig::fromArray([ 'chrome_binary' => '/usr/bin/chromium',]);容器准备与 sandbox 抉择
标题为“容器准备与 sandbox 抉择”的章节在容器中,如果没有额外的内核 capability,Chrome 的操作系统 sandbox 往往无法以 root/PID 1 身份初始化。你有两种选择:
- 保留 sandbox(建议)。 以非 root 用户运行 worker,并授予容器 Chrome sandbox 所需的 capability(通常是
SYS_ADMIN,或使用允许创建 user namespace 的 seccomp 配置文件)。这可以让 Chrome 的进程隔离保持完整。 - 禁用 sandbox。 设置
no_sandbox: true。Chrome 会以--no-sandbox启动。这会移除 Chrome 的进程隔离 sandbox:它确实会降低围堵能力,并不是一个装饰性标志。只有在无法启用 sandbox 时才使用它,并让 Chrome 在受限容器内以非 root 用户运行,同时把这类部署视为对输入信任要求更高的场景。bridge 的网络屏障(CSP 加上 CDP 封锁)在两种做法下仍然生效,但它们无法取代进程隔离。这与 OWASP ASVS 对渲染不受信任内容时最小权限与隔离的指引一致。
完整的边界说明(sandbox 保护什么、不保护什么)位于 /integrations/artisan/security-and-operations/ 页面。本页并未宣称禁用 sandbox 是安全的。
参考容器样板
标题为“参考容器样板”的章节FROM php:8.4-cliRUN apt-get update && apt-get install -y --no-install-recommends \ chromium fonts-liberation \ && rm -rf /var/lib/apt/lists/*RUN useradd -m -u 10001 workerUSER workerENV CHROME_BINARY=/usr/bin/chromium# Set CHROME_NO_SANDBOX=1 only if the sandbox cannot be enabled in your runtime.请以 worker(uid 10001)身份运行 worker,而不是 root。bridge 已应用 --disable-dev-shm-usage 标志,可避免容器中常见的、因 /dev/shm 过小且未进一步调优而导致的崩溃。
bridge 会封锁远程字体抓取(--disable-remote-fonts 加上 CSP)。请在操作系统层安装所需字体,或将以 data: URI 形式提供的 @font-face 来源内嵌到 defaultCss 或 HTML 中。CJK 输出需要在镜像中安装一个 CJK 字体包(例如 fonts-noto-cjk)。
健康检查探针
标题为“健康检查探针”的章节使用这个独立探针,可以在不启动主应用程序的情况下演练完整的 bridge 路径:
<?php
declare(strict_types=1);
use NextPDF\Artisan\ChromeHtmlRenderer;use NextPDF\Artisan\ChromeRendererConfig;
require __DIR__ . '/vendor/autoload.php';
$renderer = new ChromeHtmlRenderer( ChromeRendererConfig::fromArray([ 'chrome_binary' => getenv('CHROME_BINARY') ?: null, 'no_sandbox' => (bool) getenv('CHROME_NO_SANDBOX'), ]),);
$result = $renderer->render('<p>ok</p>', 200.0, 0.0);fwrite(STDOUT, strlen($result->getPdfData()) > 0 ? "CHROME_OK\n" : "CHROME_EMPTY\n");$renderer->close();CHROME_OK 表示启动、渲染与导入都已成功。抛出的异常就是确切的失败原因。请在 /integrations/artisan/troubleshooting/ 页面中对照排查。在编排式部署中,请将它接入为就绪检查。
资源隔离须知
标题为“资源隔离须知”的章节- 以专属的非 root 用户运行 Chrome。
- 应用一个主机内存上限;bridge 会通过每 100 次渲染重启来限制增长,但仍需要主机级别的上限。
- 在任何不受信任输入可达的路径上,请将
render_timeout与上游请求预算配合使用。 - 不要对外开放 Chrome 的远程调试端口。bridge 并不使用它,而开放的 CDP 端口是一条未经验证的控制通道。
失败模式与故障排查
标题为“失败模式与故障排查”的章节| 症状 | 可能原因 | 查看位置 |
|---|---|---|
ChromeNotAvailableException | chrome-php/chrome 尚未安装 | 参阅 /integrations/artisan/install/ 一节 |
首次渲染时出现 ChromeRenderException | 找不到可执行文件/sandbox 无法初始化 | 本页;/integrations/artisan/troubleshooting/ 一节 |
| PDF 为空 | 看不到方框/Chrome 崩溃 | 参阅 /integrations/artisan/troubleshooting/ 一节 |
| 远程图像空白 | 网络依设计被封锁 | 参阅 /integrations/artisan/security-and-operations/ 一节 |
| 周期性延迟尖峰 | 每 100 次渲染重启 | 参阅 /integrations/artisan/production-usage/ 一节 |
另请参阅
标题为“另请参阅”的章节- 参阅 /integrations/artisan/install/ 一节
- 参阅 /integrations/artisan/configuration/ 一节
- 参阅 /integrations/artisan/security-and-operations/ 一节
- 参阅 /integrations/artisan/troubleshooting/ 一节
- 参阅 /integrations/artisan/production-usage/ 一节