NextPDF Artisan 向け Chrome レンダラーのセットアップ
ブリッジは chrome-php/chrome を介して、ローカルの Chrome/Chromium プロセスを起動・制御します。このページでは、レンダリングを正常に行うために必要なランタイムのセットアップと、コンテナーおよびサンドボックスに関する判断ポイントを説明します。
ブリッジが Chrome と通信する仕組み
「ブリッジが Chrome と通信する仕組み」という見出しのセクションBrowserPool は chrome-php/chromeBrowserFactory を構築し(バイナリパスは任意で明示指定できます)、固定されたフラグセットで Chrome を起動します: headless: true、keepAlive: true、windowSize: [1200, 800]、sendSyncDefaultTimeout: renderTimeout * 1000、および /integrations/artisan/configuration/ ページに記載されているカスタムフラグです。その後、ブリッジは Chrome DevTools Protocol を介して、起動したプロセスを制御します。リモートデバッグポート経由で別途実行中の 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ワーカーユーザーとしてヘッドレスで実行できることを確認します:
chromium --headless --dump-dom about:blank終了コードが 0 で DOM が空であれば、バイナリと必要な共有ライブラリがそろっていることを意味します。0 以外の終了コードは、ブリッジでは ChromeRenderException として表面化するものと同じ失敗です。まずこの段階で修正してください。
ブリッジにバイナリを指定する
「ブリッジにバイナリを指定する」という見出しのセクション自動検出(chrome-php/chrome のデフォルト)は、バイナリが標準パスにある場合に機能します。本番環境で決定性を確保するには、明示的に固定してください:
$config = new ChromeRendererConfig( chromeBinaryPath: '/usr/bin/chromium',);または配列設定を使用します:
$config = ChromeRendererConfig::fromArray([ 'chrome_binary' => '/usr/bin/chromium',]);コンテナーの準備とサンドボックスの判断
「コンテナーの準備とサンドボックスの判断」という見出しのセクションコンテナー内では、追加のカーネルケーパビリティがないと、Chrome の OS サンドボックスが root / PID 1 として初期化できないことがよくあります。選択肢は 2 つあります:
- サンドボックスを維持する(推奨)。 ワーカーを非 root ユーザーとして実行し、Chrome のサンドボックスに必要なケーパビリティ(一般的には
SYS_ADMIN、またはユーザー名前空間の作成を許可する seccomp プロファイル)をコンテナーに付与します。これにより、Chrome のプロセス分離がそのまま維持されます。 - サンドボックスを無効化する。
no_sandbox: trueを設定します。Chrome は--no-sandboxを付けて起動します。これにより、Chrome のプロセス分離サンドボックスが除去されます。これは単なる形式的なフラグではなく、実質的に封じ込めが弱まります。サンドボックスを有効化できない場合に限って使用し、制約されたコンテナー内で Chrome を非 root ユーザーとして実行し、その配備では入力に対してより高い信頼を前提にするものとして扱ってください。ブリッジのネットワークバリア(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.ワーカーは root ではなく worker(uid 10001)として実行してください。ブリッジはすでに --disable-dev-shm-usage フラグを適用しており、これによって、追加チューニングのないコンテナーでよく発生する /dev/shm が小さいことによるクラッシュを回避します。
ブリッジはリモートフォントの取得をブロックします(--disable-remote-fonts と CSP)。必要なフォントは OS レイヤーにインストールするか、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/ ページで照合してください。オーケストレーションされた配備では、これを readiness チェックとして組み込んでください。
リソース分離に関する注意事項
「リソース分離に関する注意事項」という見出しのセクション- 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/(本番環境での使用)