Configurare il renderer Chrome per NextPDF Artisan
In breve
Sezione intitolata “In breve”Il bridge avvia e controlla un processo Chrome/Chromium locale tramite chrome-php/chrome. Questa pagina descrive come configurare tale runtime affinché il rendering completi correttamente e chiarisce le decisioni relative a container e sandbox.
Come il bridge comunica con Chrome
Sezione intitolata “Come il bridge comunica con Chrome”BrowserPool crea un chrome-php/chromeBrowserFactory (eventualmente con un percorso esplicito del binario) e avvia Chrome con un insieme fisso di flag: headless: true, keepAlive: true, windowSize: [1200, 800], sendSyncDefaultTimeout: renderTimeout * 1000 e i flag personalizzati elencati nella pagina /integrations/artisan/configuration/. Il bridge controlla poi il processo avviato tramite il Chrome DevTools Protocol. Non si collega a un’istanza di Chrome separata già in esecuzione tramite una porta di debug remoto, quindi non esiste alcun endpoint di rete da esporre o autenticare. Chrome viene eseguito come processo figlio del worker PHP. Il test tests/Unit/Artisan/BrowserPoolTest.php::getBrowserCreatesAndReusesInstanceWithExpectedOptions verifica esattamente queste opzioni di avvio.
Preparare il binario
Sezione intitolata “Preparare il binario”Installare una build di Chrome o Chromium eseguibile dall’utente che esegue il worker:
# Debian / Ubuntuapt-get install -y chromium
# RHEL / Fedoradnf install -y chromium
# Alpine (containers)apk add --no-cache chromium nss freetype harfbuzz ttf-freefontVerificare che possa essere eseguito in modalità headless dallo stesso utente:
chromium --headless --dump-dom about:blankUn codice di uscita 0 con un DOM vuoto indica che il binario e le relative librerie condivise sono presenti. Un codice di uscita diverso da zero corrisponde allo stesso errore che il bridge espone come ChromeRenderException. Risolverlo prima a questo livello.
Indirizzare il bridge verso il binario
Sezione intitolata “Indirizzare il bridge verso il binario”Il rilevamento automatico (predefinito in chrome-php/chrome) funziona quando il binario si trova in un percorso standard. Per ottenere un comportamento deterministico in produzione, specificarlo esplicitamente:
$config = new ChromeRendererConfig( chromeBinaryPath: '/usr/bin/chromium',);oppure tramite una configurazione basata su array:
$config = ChromeRendererConfig::fromArray([ 'chrome_binary' => '/usr/bin/chromium',]);Provisioning del container e scelta della sandbox
Sezione intitolata “Provisioning del container e scelta della sandbox”In un container, la sandbox del sistema operativo di Chrome spesso non si inizializza quando il processo viene eseguito come root / PID 1 senza capability aggiuntive del kernel. Sono disponibili due opzioni:
- Mantenere la sandbox (consigliato). Eseguire il worker come utente non root e concedere al container le capability richieste dalla sandbox di Chrome (di norma
SYS_ADMINo un profilo seccomp che consenta la creazione di user namespace). In questo modo l’isolamento di processo di Chrome rimane intatto. - Disabilitare la sandbox. Impostare
no_sandbox: true. Chrome viene avviato con--no-sandbox. Questo rimuove la sandbox di isolamento di processo di Chrome: una reale riduzione del contenimento, non un flag puramente cosmetico. Utilizzarlo solo dove la sandbox non può essere abilitata, eseguire Chrome come utente non root all’interno di un container vincolato e trattare il deployment come se richiedesse un livello di fiducia più elevato nell’input. Le barriere di rete del bridge (CSP + blocco CDP) restano comunque attive, ma non sostituiscono l’isolamento di processo. Ciò è in linea con le indicazioni OWASP ASVS su privilegio minimo e isolamento per il rendering di contenuti non attendibili.
La descrizione completa dei confini, ovvero ciò che la sandbox protegge e ciò che non protegge, si trova nella pagina /integrations/artisan/security-and-operations/. Questa pagina non afferma che disabilitare la sandbox sia sicuro.
Struttura del container di riferimento
Sezione intitolata “Struttura del container di riferimento”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.Eseguire il worker come worker (uid 10001), non come root. Il bridge applica già il flag --disable-dev-shm-usage, che evita l’arresto anomalo dovuto a un /dev/shm troppo piccolo, un caso comune nei container senza ulteriori ottimizzazioni.
Il bridge blocca il recupero dei font remoti (--disable-remote-fonts e CSP). Installare i font necessari a livello di sistema operativo oppure incorporarli come URI data: con sorgenti @font-face all’interno di defaultCss o nell’HTML. L’output CJK richiede un pacchetto di font CJK (ad esempio fonts-noto-cjk) installato nell’immagine.
Probe di integrità
Sezione intitolata “Probe di integrità”Utilizzare questo probe autonomo per verificare l’intero percorso del bridge senza passare dall’applicazione host:
<?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 conferma avvio, rendering e importazione. Se viene sollevata un’eccezione, questa indica l’errore preciso. Confrontare l’errore con la pagina /integrations/artisan/troubleshooting/. Integrarlo come controllo di readiness nei deployment orchestrati.
Note sull’isolamento delle risorse
Sezione intitolata “Note sull’isolamento delle risorse”- Eseguire Chrome come utente non root dedicato.
- Applicare un limite di memoria a livello di host; il bridge contiene la crescita con un riavvio ogni 100 rendering, ma è comunque necessario un tetto massimo a livello di host.
- Abbinare
render_timeouta un budget di richiesta a monte su qualsiasi percorso raggiungibile da input non attendibile. - Non esporre alcuna porta di debug remoto di Chrome. Il bridge non ne utilizza alcuna e una porta CDP aperta costituisce un canale di controllo non autenticato.
Modalità di errore e risoluzione dei problemi
Sezione intitolata “Modalità di errore e risoluzione dei problemi”| Sintomo | Causa probabile | Dove cercare |
|---|---|---|
ChromeNotAvailableException | chrome-php/chrome non installato | /integrations/artisan/install/ |
ChromeRenderException al primo rendering | Binario mancante / la sandbox non riesce a inizializzarsi | Questa pagina; /integrations/artisan/troubleshooting/ |
| PDF vuoto | Nessun riquadro visibile / arresto anomalo di Chrome | /integrations/artisan/troubleshooting/ |
| Immagini remote vuote | Rete bloccata per scelta progettuale | /integrations/artisan/security-and-operations/ |
| Picco di latenza periodico | Riavvio ogni 100 rendering | /integrations/artisan/production-usage/ |
Vedere anche
Sezione intitolata “Vedere anche”- /integrations/artisan/install/
- /integrations/artisan/configuration/
- /integrations/artisan/security-and-operations/
- /integrations/artisan/troubleshooting/
- /integrations/artisan/production-usage/