Uruchamianie NextPDF na platformach serverless
W skrócie
Dział zatytułowany „W skrócie”Natywny, działający w procesie rdzeniowy silnik NextPDF to niemal idealne
obciążenie serverless. To czysty PHP działający wewnątrz twojego procesu —
composer require nextpdf/core, zbuduj dokument, odbierz bajty. Nie ma
zewnętrznego pliku binarnego do uruchomienia, nie ma przeglądarki headless, nie
ma demona do utrzymywania przy życiu ani gniazda do usługi sidecar. Funkcja,
która buduje PDF, startuje na zimno, uruchamia twój PHP, zwraca bajty i kończy
działanie. To czysto mapuje się na AWS Lambda (przez środowisko Bref), Google
Cloud Run oraz AWS App Runner.
Ta strona opisuje wdrożenie tego natywnego silnika do tych trzech środowisk oraz niewielki zestaw rzeczywistych ograniczeń, które one narzucają:
- system plików środowiska uruchomieniowego jest nietrwały: Lambda gwarantuje
jedynie zapisywalny
/tmp, podczas gdy środowiska kontenerowe (Cloud Run, App Runner) mają ulotny, ograniczony do kontenera system plików — tak czy inaczej czcionki muszą podróżować wewnątrz paczki wdrożeniowej lub obrazu i być zarejestrowane w PHP (silnik nie odczytuje żadnej zmiennej środowiskowej ze ścieżką czcionek); - zimne starty płacą za autoloading i ewentualne rozgrzewanie czcionek, więc
rozgrzej
FontRegistryraz na kontener, a nie raz na wywołanie; - rozmiar paczki, pamięć i limit czasu muszą być dobrane do budowy, a nie do trywialnego żądania.
Ta strona jest wyłącznie o natywnym silniku. Mostek Chrome
(writeHtmlChrome przez sugerowany pakiet nextpdf/artisan) to inna,
cięższa historia: uruchamia headless Chromium przez symfony/process, którego
zwykły zip Lambdy ani szczupły kontener nie zawierają. Uruchomienie Chromium na
Lambdzie oznacza niestandardową warstwę z przeglądarką i jej bibliotekami
współdzielonymi, znacznie większe paczki i znacznie dłuższe zimne starty — poza
zakresem tutaj. Sam silnik nie potrzebuje nic z tego.
Zanim zaczniesz, potwierdź, że te elementy są na swoim miejscu:
- Twoja aplikacja ma zatwierdzone
composer.jsonicomposer.lock, znextpdf/corejako zależnością. - Masz pliki czcionek, które zamierzasz osadzić, i masz licencję na ich osadzenie.
- Masz łańcuch narzędzi dla swojego celu — CLI Bref i framework
serverlessdla Lambdy lub build kontenera dla Cloud Run / App Runner.
Dlaczego natywny silnik pasuje do serverless
Dział zatytułowany „Dlaczego natywny silnik pasuje do serverless”Czytając wprost z pakietu, nextpdf/core wymaga php: >=8.4 <9.0 oraz
niewielkiego zestawu rozszerzeń PHP — ext-mbstring, ext-intl, ext-gd,
ext-openssl, ext-zlib oraz ext-curl. Standardowe warstwy PHP Bref dołączają
każde z nich. Oficjalne obrazy kontenerowe php:8.4 dostarczają openssl,
curl i zlib od razu, ale mbstring, gd i intl nie są dołączone —
wymagają zainstalowania zależności systemowych i włączenia rozszerzeń za pomocą
docker-php-ext-install (zobacz
przewodnik wdrażania w Dockerze).
W Bref nie ma nic egzotycznego do kompilacji; na ścieżce kontenerowej włączasz
te trzy rozszerzenia w buildzie obrazu dla samego silnika.
To, co czyni dopasowanie czystym, to to, czego silnik nie robi:
- Brak podprocesu dla ścieżki rdzeniowej. Budowanie dokumentu i wywołanie
getPdfData()to PHP działający w procesie od początku do końca. Zależnośćsymfony/processistnieje dla opcjonalnego mostka Chrome, a nie dla natywnego renderowania — natywne generowanie PDF nigdy nie uruchamia procesu. - Brak stanu trwałego. Każde wywołanie buduje świeży dokument i zwraca bajty. Nic nie musi przetrwać między żądaniami poza ciepłym kontenerem, który wykorzystujesz do rozgrzewania czcionek (poniżej), ale nigdy nie polegasz na nim dla poprawności.
- Brak potrzeby zapisywalnego katalogu roboczego. Silnik buduje PDF w pamięci
i zwraca go jako łańcuch znaków; dotyka dysku tylko wtedy, gdy ty wywołasz
save(). Na serverless tego nie robisz — zwracasz bajty — więc brak trwałego systemu plików nigdy nie gryzie ścieżki budowy.
Jedno twarde ograniczenie: brak trwałego, zapisywalnego systemu plików
Dział zatytułowany „Jedno twarde ograniczenie: brak trwałego, zapisywalnego systemu plików”System plików wdrożenia nie jest trwały, ale model różni się w zależności od
środowiska. AWS Lambda gwarantuje jedynie zapisywalny /tmp (domyślnie
512 MB, konfigurowalny do 10 GB); reszta systemu plików funkcji jest tylko do
odczytu. Środowiska kontenerowe (Cloud Run, App Runner) mają ulotny,
ograniczony do kontenera zapisywalny system plików zamiast modelu wyłącznie
/tmp — ale wszystko, co tam zapisane, jest tracone, gdy kontener jest
przetwarzany ponownie, więc to przestrzeń robocza, a nie magazyn. W każdym
przypadku preferuj /tmp lub skonfigurowany wolumen do przygotowywania i nigdy
nie polegaj na zapisach do ścieżki obrazu aplikacji jako na trwałym magazynie.
Wynikają z tego dwie konsekwencje.
Nigdy nie wywołuj save() w oczekiwaniu na trwały wynik.
NextPDF\Core\Document udostępnia zarówno save(string $path): void, jak i
getPdfData(): string. Na serverless używasz getPdfData() i zwracasz lub
przesyłasz bajty — nie traktuj zapisu do katalogu aplikacji jako trwałego
magazynu. Jeśli musisz przygotować plik (na przykład do przesłania
wieloczęściowego do magazynu obiektów), zapisz pod /tmp (lub skonfigurowanym
wolumenem) i posprzątaj, pamiętając, że na ciepłym kontenerze ta przestrzeń
robocza przetrwa między wywołaniami i liczy się do jej limitu rozmiaru.
use NextPDF\Core\Document;
// Right for serverless: get the bytes, return or upload them.$pdf = $document->getPdfData(); // string of PDF bytes, built in memory
// Avoid on serverless: save() writes to disk. On Lambda the application// directory is read-only; on Cloud Run / App Runner it is writable but// ephemeral (lost on container recycle). Neither is durable storage.// $document->save('/var/task/out.pdf'); // not durable — return the bytes insteadNie instaluj czcionek systemu operacyjnego w czasie działania i nie polegaj na
automatycznym wykrywaniu czcionek; spakuj swoje pliki czcionek na produkcję. Na
Lambdzie system plików tylko do odczytu blokuje apt-get install fonts-*
całkowicie; na środowisku kontenerowym każda instalacja w czasie działania ląduje
na ulotnym systemie plików i jest tracona przy następnym przetworzeniu. I tak by
to nie pomogło, bo natywny silnik nie odczytuje żadnych czcionek
OS/fontconfig — rozpoznaje czcionki wyłącznie z plików, które zarejestrujesz.
Dlatego na produkcję pliki czcionek muszą znajdować się wewnątrz artefaktu
wdrożeniowego. Jeśli celowo pobierasz pliki czcionek do /tmp lub
skonfigurowanego wolumenu, musisz jawnie zarejestrować je w rejestrze czcionek i
zaakceptować dodatkowy koszt zimnego startu oraz niezawodności — to nie jest
zalecany wzorzec produkcyjny.
Spakuj i zarejestruj czcionki w paczce lub obrazie
Dział zatytułowany „Spakuj i zarejestruj czcionki w paczce lub obrazie”Natywny silnik rozpoznaje czcionki z plików czcionek przez
NextPDF\Typography\FontRegistry, a nie z fontconfig ani czcionek
zainstalowanych w systemie operacyjnym. Na serverless to nie podlega
negocjacji: nie ma trwałego systemu plików, na którym można umieścić czcionki po
wdrożeniu, więc podróżują wewnątrz paczki (zip lub warstwy Lambdy) albo wewnątrz
obrazu (Cloud Run / App Runner).
Spakuj swoje pliki .ttf / .otf / .ttc pod katalogiem w projekcie —
resources/fonts/ to konwencja — tak aby zostały włączone do artefaktu.
Następnie zarejestruj ten katalog w PHP. Silnik nie odczytuje żadnej zmiennej
środowiskowej ze ścieżką czcionek: NEXTPDF_FONTS_PATH to domyślna wartość
klucza konfiguracji fonts_path pakietu nextpdf/laravel
(env('NEXTPDF_FONTS_PATH', resource_path('fonts'))) i jest konsumowana wyłącznie
przez tę integrację z frameworkiem, a nie przez nextpdf/core. Sama funkcja musi
zbudować rejestr z dołączonym katalogiem:
use NextPDF\Typography\FontRegistry;use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;
// Register the directory the deployment artifact bundled the fonts into.// On Lambda/Bref the code root is /var/task; adjust for your runtime.$registry = new FontRegistry(__DIR__ . '/resources/fonts');// (equivalently, $registry->addFontDirectory(__DIR__ . '/resources/fonts');)
$factory = new DocumentFactory($registry, new ImageRegistry(maxCacheBytes: 0));$document = $factory->create();To cała kwestia serverless dla czcionek. Reguły nazewnictwa plików, pełne API rejestru oraz obsługa nietrwałego systemu plików znajdują się na dedykowanej stronie — nie powielaj ich tutaj. Przeczytaj Udostępnianie czcionek dla natywnego silnika na produkcji po pełny wzorzec i zarejestruj ten sam katalog, który spakowałeś. Przewodnik wdrażania w Dockerze omawia równoważne pakowanie po stronie obrazu dla przypadku Cloud Run / App Runner.
Zimne starty: rozgrzej FontRegistry raz na kontener
Dział zatytułowany „Zimne starty: rozgrzej FontRegistry raz na kontener”Zimny start płaci za bootstrap PHP, zoptymalizowany autoloader Composera oraz ewentualne parsowanie czcionek, które uruchamia pierwsza budowa. Nie możesz uniknąć bootstrapu, ale możesz przenieść pracę z czcionkami poza gorącą ścieżkę i wykorzystać ją ponownie między ciepłymi wywołaniami.
Zbuduj FontRegistry i DocumentFactory raz, poza handlerem, tak aby żyły
przez całe życie kontenera i były wykorzystywane ponownie przy każdym ciepłym
wywołaniu. Opcjonalnie wywołaj warmup() z plikami czcionek, o których wiesz, że
ich użyjesz, tak aby zostały sparsowane podczas inicjalizacji, a nie przy
pierwszym renderowaniu, a następnie lock() rejestru, aby jego sparsowany stan
był zamrożony i żadna mutacja przy wywołaniu nie mogła się ścigać:
use NextPDF\Typography\FontRegistry;use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;
// Container-scoped, built once at cold start (module scope, not per request).$fontsDir = __DIR__ . '/resources/fonts';$registry = new FontRegistry($fontsDir);
// Parse the fonts you will actually use now, so the first render does not.$registry->warmup([ $fontsDir . '/liberation/LiberationSans-Regular.ttf', $fontsDir . '/liberation/LiberationSans-Bold.ttf',]);
// Freeze the parsed state for the life of the warm container.$registry->lock();
$factory = new DocumentFactory($registry, new ImageRegistry(maxCacheBytes: 0));
// Each invocation: fresh document from the shared, warm factory.$handler = static function (array $event) use ($factory): string { $document = $factory->create(); $document->addPage(); $document->cell(0, 10, 'Hello from serverless', newLine: true);
return $document->getPdfData();};Wywołaj warmup() przed lock() — rejestr jest zamrażany po zablokowaniu,
więc warmup po tym podnosi błąd konfiguracji. Traktuj czcionkę, która nie wczytuje
się przy rozgrzewaniu, jako błąd na etapie wdrożenia, a nie szczegół czasu
działania: zweryfikuj, że każda ścieżka czcionki, którą zamierzasz rozgrzać,
faktycznie istnieje i parsuje się przy starcie, i przerwij wdrożenie (lub swój
health check), jeśli któraś nie, zamiast pozwolić, by błędnie wpisana ścieżka
ujawniła się później jako brakujące glify. Utrzymuj listę rozgrzewania
ograniczoną do czcionek, których potrzebuje typowe wywołanie; rozgrzewanie dużej
rodziny, której rzadko używasz, jedynie wydłuża każdy zimny start.
Funkcja Bref na AWS Lambda
Dział zatytułowany „Funkcja Bref na AWS Lambda”Bref dostarcza środowisko PHP dla Lambdy jako opublikowaną
warstwę oraz plugin serverless.yml. Środowisko php-84 już dostarcza
rozszerzenia, których potrzebuje nextpdf/core, więc wdrażasz swój kod i czcionki
i kierujesz funkcję na handler. Minimalny serverless.yml:
service: nextpdf-serverless
provider: name: aws region: us-east-1 runtime: provided.al2023
plugins: - ./vendor/bref/bref
functions: generate: handler: handler.php description: Generate a PDF with the native NextPDF engine runtime: php-84 memorySize: 1024 # size to the build; see "Sizing" below timeout: 30 # seconds; raise for large documents # The Lambda filesystem is read-only except /tmp. Fonts ship in the # package under resources/fonts and are registered in the handler.Handler buduje dokument z ciepłą, ograniczoną do kontenera fabryką i zwraca
bajty. Dla API HTTP zwróć je zakodowane w base64 z typem zawartości
application/pdf, aby API Gateway traktował treść jako binarną; dla wyzwalacza
invoke lub kolejki prześlij bajty do magazynu obiektów i zwróć klucz:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
// --- Cold-start: built once per container, reused across warm invocations. ---$fontsDir = __DIR__ . '/resources/fonts';$registry = new FontRegistry($fontsDir);$registry->warmup([$fontsDir . '/liberation/LiberationSans-Regular.ttf']);$registry->lock();$factory = new DocumentFactory($registry, new ImageRegistry(maxCacheBytes: 0));
// --- Per-invocation handler. ---return static function (array $event) use ($factory): array { $document = $factory->create(); $document->addPage(); $document->cell(0, 10, 'Invoice', newLine: true);
// getPdfData() materializes the whole PDF in memory and returns it. $bytes = $document->getPdfData();
return [ 'statusCode' => 200, 'isBase64Encoded' => true, 'headers' => ['Content-Type' => 'application/pdf'], 'body' => base64_encode($bytes), ];};Zweryfikuj, że paczka zawiera zdrowe środowisko, zanim skierujesz na nią ruch.
nextpdf/core dostarcza CLI zainstalowane w vendor/bin/nextpdf, którego
polecenie doctor raportuje dokładnie te rozszerzenia, których potrzebuje silnik.
Uruchom je raz względem tego samego obrazu lub warstwy środowiska, aby potwierdzić,
że PHP 8.4 i każde wymagane rozszerzenie jest obecne.
Cloud Run i App Runner
Dział zatytułowany „Cloud Run i App Runner”Cloud Run i App Runner uruchamiają kontener, a nie spakowaną funkcję, więc
buildem jest obraz Dockera z
Konteneryzacji aplikacji NextPDF,
a nie paczka Bref. Ograniczenia natywnego silnika są identyczne: spakuj czcionki
do obrazu, zarejestruj spakowany katalog w PHP, uruchamiaj bez uprawnień i
traktuj system plików jako nietrwały. W odróżnieniu od modelu wyłącznie /tmp
Lambdy, kontener Cloud Run / App Runner ma ulotny, ograniczony do kontenera
zapisywalny system plików — ale jest on resetowany przy każdym przetworzeniu, więc
używaj /tmp (tmpfs na Cloud Run) lub skonfigurowanego wolumenu jako przestrzeni
roboczej i nigdy nie polegaj na zapisach do ścieżki obrazu aplikacji jako na
trwałym magazynie.
Różnice względem Lambdy są operacyjne, a nie strukturalne:
- Kontener może pozostać ciepły między żądaniami przy ustawieniu
współbieżności, więc rozgrzewanie ograniczonego do kontenera
FontRegistry/DocumentFactorypowyżej opłaca się przez wiele żądań, a nie tylko przy następnym wywołaniu. - Serwujesz przez HTTP (SAPI FPM lub wbudowanego serwera PHP), a nie zdarzenie invoke, więc zwracasz bajty przez odpowiedź swojego frameworka. Dla dużego dokumentu zwróć je jako odpowiedź strumieniowaną — zobacz Strumieniowe przesyłanie dużego wygenerowanego PDF jako odpowiedź HTTP.
- Limit czasu żądania i pamięć są ustawiane na usłudze (limit czasu / pamięć usługi Cloud Run; konfiguracja instancji App Runner), a nie per funkcja.
Wszystko inne — zestaw rozszerzeń, rejestracja czcionek, wywołanie wyjściowe
getPdfData() — to ten sam kod co handler Lambdy.
Dobór rozmiaru: paczka, pamięć i limit czasu
Dział zatytułowany „Dobór rozmiaru: paczka, pamięć i limit czasu”- Rozmiar paczki i obrazu. Artefakt niesie
vendor/(tylko produkcja — instaluj z--no-dev) oraz spakowane czcionki. Czcionki dominują: pełna rodzina CJK to dziesiątki megabajtów. Dostarczaj tylko czcionki, które faktycznie renderujesz, aby utrzymać paczkę Lambdy poniżej jej limitów i obraz mały, co także skraca zimne starty. Dołączona rodzina Liberation (resources/fonts/liberation/) jest mała i pokrywa kompatybilne metrycznie podstawienie Helvetiki. - Pamięć.
getPdfData()buduje cały dokument w pamięci i zwraca go jako jeden łańcuch znaków, więc szczytowa pamięć to z grubsza rozmiar jednego gotowego PDF plus zestaw roboczy budowy. Dobierz pamięć funkcji/kontenera do największego dokumentu, jaki generujesz, a nie do średniego. Na Lambdzie pamięć skaluje także CPU, więc więcej pamięci często oznacza szybszą budowę i tańsze uruchomienie mimo wyższej stawki za milisekundę — zmierz obie wartości. Kilkustronicowy dokument jest wygodny przy 512–1024 MB; dokumenty z dużą ilością obrazów lub wieloma stronami potrzebują więcej. - Limit czasu. Budowa, a nie transfer, dominuje budżet żądania. Ustaw limit czasu funkcji powyżej najgorszego przypadku czasu budowy z zapasem. Jeśli dokument jest na tyle duży, by ryzykować przekroczenie limitu, przenieś generowanie na wyzwalacz asynchroniczny (Lambda oparta na kolejce lub zadanie Cloud Run), który zapisuje wynik do magazynu obiektów zamiast blokować żądanie synchroniczne.
- Rozmiar
/tmp. Jeśli przygotowujesz cokolwiek pod/tmp, uwzględnij jego limit rozmiaru i pamiętaj, że przetrwa między ciepłymi wywołaniami — posprzątaj, bo długo żyjący kontener powoli go zapełnia.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Brak trwałego
save()do katalogu aplikacji. System plików wdrożenia nie jest trwały — katalog aplikacji Lambdy jest tylko do odczytu (zapisy przyjmuje tylko/tmp), a system plików kontenera Cloud Run / App Runner jest zapisywalny, ale ulotny. UżyjgetPdfData()i zwróć/prześlij bajty; przygotowuj pod/tmplub skonfigurowanym wolumenem, jeśli musisz. - Nie polegaj na automatycznym wykrywaniu czcionek. Nie instaluj czcionek
systemu operacyjnego w czasie działania i nie polegaj na automatycznym
wykrywaniu czcionek; spakuj swoje pliki czcionek na produkcję. Natywny silnik
nie odczytuje żadnych czcionek OS/fontconfig — rozpoznaje wyłącznie pliki, które
zarejestrujesz. Jeśli celowo pobierasz pliki czcionek do
/tmplub skonfigurowanego wolumenu, musisz jawnie zarejestrować je w rejestrze czcionek i zaakceptować dodatkowy koszt zimnego startu oraz niezawodności. Spakuj i zarejestruj pliki. Zobacz stronę o czcionkach linkowaną powyżej. NEXTPDF_FONTS_PATHnic nie robi dla samego silnika. To domyślna wartość konfiguracjinextpdf/laravel, a nie zmienna, którą odczytujenextpdf/core. Sam handler Bref, który ustawia tylko tę zmienną, nie rejestruje żadnych czcionek i renderuje tofu.- Mostek Chrome nie pasuje do zwykłej funkcji.
writeHtmlChromepotrzebuje headless Chromium i ścieżki podprocesusymfony/process. Umieszczenie Chromium na Lambdzie wymaga niestandardowej warstwy z przeglądarką i jej bibliotekami, znacznie większych paczek i długich zimnych startów. Natywny silnik iwriteHtmlnie potrzebują nic z tego — preferuj je na serverless. - Koszt zimnego startu to autoload plus parsowanie czcionek. Użyj
--optimize-autoloaderprzy instalacji produkcyjnej i rozgrzej rejestr raz na kontener. Nie rozgrzewaj czcionek, których rzadko używasz. - API Gateway wymaga obsługi binarnej. Zwróć
isBase64Encoded: truezContent-Type: application/pdfi skonfiguruj API tak, by traktowałoapplication/pdfjako binarny typ mediów, bo inaczej klient otrzyma uszkodzone bajty. - Premium i ionCube to cięższa kwestia artefaktu. Buildy NextPDF Pro / Enterprise zakodowane w ionCube potrzebują loadera ionCube dopasowanego do dokładnego buildu PHP w środowisku, którego standardowa warstwa Bref nie zawiera. To poza zakresem wdrożenia serverless dla rdzenia.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”- Nie dostarczaj zależności deweloperskich. Instaluj z
--no-dev, aby narzędzia testowe i analizy nigdy nie trafiły do paczki funkcji ani obrazu. - Waliduj wejście przed budowaniem. Budowa PDF sterowana wejściem z żądania to wektor wyczerpania pamięci; odrzuć wejścia spoza zakresu lub zbyt duże na granicy, zanim ruszy jakakolwiek praca budowy, i ogranicz współbieżność, aby duży ruch nie zwielokrotnił szczytowej pamięci do awarii braku pamięci.
- Trzymaj czcionki i licencje poza publicznymi artefaktami. Pakuj tylko czcionki, na które masz licencję, i nigdy nie wbudowuj pliku licencji premium do publicznie wypchniętego obrazu lub warstwy — zamiast tego dostarczaj go w czasie działania przez wartość środowiskową lub menedżer sekretów.
- Najmniejsze uprawnienia. Nadaj funkcji/usłudze tylko te uprawnienia IAM, których potrzebuje (na przykład dostęp do zapisu do jednego docelowego bucketa), i uruchamiaj kontener bez uprawnień, jak pokazuje przewodnik Dockera.
Zgodność
Dział zatytułowany „Zgodność”Ten przewodnik nie formułuje normatywnego twierdzenia o standardach. Fakty
platformowe są odczytane bezpośrednio z pakietu nextpdf/core: ograniczenie
php: >=8.4 <9.0 oraz wymagane rozszerzenia ext-mbstring, ext-intl,
ext-gd, ext-openssl, ext-zlib oraz ext-curl. Standardowa warstwa
środowiska Bref PHP-8.4 dostarcza wszystkie sześć; oficjalny obraz php:8.4
dostarcza openssl, curl i zlib, ale mbstring, gd i intl muszą zostać
zainstalowane i włączone w buildzie obrazu za pomocą docker-php-ext-install
(zobacz stronę Dockera). Wywołanie wyjściowe to rzeczywista powierzchnia rdzenia
NextPDF\Core\Document::getPdfData(): string (jego dyskowy odpowiednik to
save(string $path): void). Czcionki są rejestrowane przez
NextPDF\Typography\FontRegistry — jego argument konstruktora z katalogiem /
addFontDirectory(), z warmup(array $fontFiles) i lock() dla wzorca zimnego
startu — podpięte przez NextPDF\Core\DocumentFactory::create().
NEXTPDF_FONTS_PATH to klucz konfiguracji fonts_path pakietu nextpdf/laravel
(env('NEXTPDF_FONTS_PATH', resource_path('fonts'))), a nie zmienna, którą
odczytuje nextpdf/core. Polecenie doctor CLI nextpdf jest zadeklarowane jako
"bin": ["bin/nextpdf"] w pakiecie i instalowane w vendor/bin/nextpdf w
aplikacji konsumującej. Nazwy środowisk Bref oraz zachowania AWS Lambda / Cloud
Run / App Runner to udokumentowane funkcje tych dostawców.
Zobacz też
Dział zatytułowany „Zobacz też”- Konteneryzacja aplikacji NextPDF: obraz produkcyjny używany dla celów Cloud Run / App Runner.
- Udostępnianie czcionek dla natywnego silnika na produkcji: nazewnictwo plików czcionek, API rejestru oraz wzorzec rozgrzej-i-zablokuj, na którym opiera się ta strona.
- Strumieniowe przesyłanie dużego wygenerowanego PDF jako odpowiedź HTTP: model pamięci dla zwracania zbudowanego dokumentu przez HTTP na Cloud Run / App Runner.
- Renderowanie na brzegu z Cloudflare: gdy funkcja działająca w procesie nie jest właściwym środowiskiem.