Настройка рендерера Chrome для NextPDF Artisan
Мост запускает локальный процесс Chrome/Chromium и управляет им через chrome-php/chrome. Используйте эту страницу, чтобы настроить среду выполнения для корректной отрисовки в формат Portable Document Format (PDF) и принять правильные решения по контейнерам и песочнице.
Как мост взаимодействует с Chrome
Заголовок раздела «Как мост взаимодействует с Chrome»BrowserPool создаёт chrome-php/chromeBrowserFactory (при необходимости с явным путём к исполняемому файлу) и запускает Chrome с фиксированным набором флагов: headless: true, keepAlive: true, windowSize: [1200, 800], sendSyncDefaultTimeout: renderTimeout * 1000 и пользовательскими флагами, перечисленными на странице /integrations/artisan/configuration/. Затем мост управляет запущенным процессом по протоколу Chrome DevTools Protocol (CDP). Он не подключается к отдельному процессу Chrome через порт удалённой отладки, поэтому не появляется сетевая конечная точка, которую пришлось бы открывать или аутентифицировать. Chrome работает как дочерний процесс рабочего процесса PHP. Тест tests/Unit/Artisan/BrowserPoolTest.php::getBrowserCreatesAndReusesInstanceWithExpectedOptions проверяет именно эти параметры запуска.
Подготовка исполняемого файла
Заголовок раздела «Подготовка исполняемого файла»Установите сборку 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Убедитесь, что браузер запускается в headless-режиме от имени пользователя рабочего процесса:
chromium --headless --dump-dom about:blankКод завершения 0 с пустой объектной моделью документа (DOM) означает, что исполняемый файл и его разделяемые библиотеки доступны. Ненулевой код завершения — тот же сбой, который мост представляет как ChromeRenderException. Сначала устраните проблему на этом уровне.
Указание моста на исполняемый файл
Заголовок раздела «Указание моста на исполняемый файл»Автоматическое обнаружение (поведение по умолчанию в chrome-php/chrome) работает, когда исполняемый файл находится в стандартном пути. Для детерминированного поведения в рабочей среде задайте путь явно:
$config = new ChromeRendererConfig( chromeBinaryPath: '/usr/bin/chromium',);или через конфигурацию в формате массива:
$config = ChromeRendererConfig::fromArray([ 'chrome_binary' => '/usr/bin/chromium',]);Подготовка контейнера и решение о песочнице
Заголовок раздела «Подготовка контейнера и решение о песочнице»В контейнере песочница операционной системы Chrome часто не может инициализироваться от имени root / с идентификатором процесса (PID) 1 без дополнительных возможностей ядра. Есть два варианта:
- Сохраните песочницу (предпочтительно). Запускайте рабочий процесс от имени пользователя без прав root и предоставьте контейнеру возможности, необходимые песочнице Chrome (обычно
SYS_ADMINили профиль seccomp, разрешающий создание пользовательских пространств имён). Так изоляция процессов Chrome остаётся без изменений. - Отключите песочницу. Задайте
no_sandbox: true. Chrome запускается с флагом--no-sandbox. Это отключает песочницу изоляции процессов Chrome: уровень изоляции действительно снижается, это не косметический флаг. Используйте этот вариант только там, где песочницу нельзя включить; запускайте Chrome от имени пользователя без прав root внутри ограниченного контейнера и рассматривайте такое развёртывание как требующее более высокого доверия к входным данным. Сетевые барьеры моста — Content Security Policy (CSP) и блокировка CDP — в любом случае остаются в силе, но они не заменяют изоляцию процессов. Это соответствует рекомендациям OWASP ASVS по наименьшим привилегиям и изоляции при отрисовке недоверенного содержимого.
Полное описание границ, включая то, от чего песочница защищает и от чего не защищает, приведено на странице /integrations/artisan/security-and-operations/. Эта страница не утверждает, что отключать песочницу безопасно.
Эталонная структура контейнера
Заголовок раздела «Эталонная структура контейнера»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 (идентификатор пользователя 10001), а не root. Мост уже применяет флаг --disable-dev-shm-usage, который предотвращает сбой из-за малого /dev/shm, часто встречающийся в контейнерах без дополнительной настройки.
Мост блокирует загрузку удалённых шрифтов (--disable-remote-fonts и CSP). Установите нужные шрифты на уровне операционной системы либо встройте их как источники data: с унифицированным идентификатором ресурса (URI) @font-face внутри defaultCss или языка гипертекстовой разметки (HTML). Для вывода на китайском, японском и корейском языках (CJK) в образе должен быть установлен пакет шрифтов CJK, например fonts-noto-cjk.
Проверка работоспособности
Заголовок раздела «Проверка работоспособности»Используйте эту автономную проверку, чтобы пройти весь путь через мост без основного приложения:
<?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/. Подключите эту проверку как проверку готовности в оркестрируемых развёртываниях.
Замечания об изоляции ресурсов
Заголовок раздела «Замечания об изоляции ресурсов»- Запускайте Chrome от имени отдельного пользователя без прав root.
- Установите ограничение памяти на хосте; мост сдерживает рост перезапуском после 100 операций отрисовки, но верхняя граница на хосте всё равно необходима.
- Сочетайте
render_timeoutс вышестоящим бюджетом запроса на любом пути, доступном для недоверенных входных данных. - Не открывайте порт удалённой отладки Chrome. Мост его не использует, а открытый порт CDP — это канал управления без аутентификации.
Виды сбоев и устранение неполадок
Заголовок раздела «Виды сбоев и устранение неполадок»| Симптом | Вероятная причина | Где искать |
|---|---|---|
ChromeNotAvailableException | chrome-php/chrome не установлен | Установка: /integrations/artisan/install/ |
ChromeRenderException при первой отрисовке | Исполняемый файл отсутствует / песочница не может инициализироваться | Эта страница; /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/