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/ 一節