Aller au contenu

NextPDF Gotenberg en production

La passerelle réalise un seul aller-retour HTTP synchrone, encadré par des validations. Elle ne réessaie pas, ne met pas en file d’attente, ne met pas en cache et ne limite pas le débit. Ces comportements relèvent de l’application qui entoure la passerelle. Cette page indique où placer chacun de ces mécanismes, et ce que la passerelle garantit, pour que tu puisses construire le reste correctement.

Traite chaque conversion comme un appel distant vers un service que tu exploites, mais que tu ne contrôles pas dans ton processus. Conçois l’intégration en tenant compte de sa latence et de ses défaillances.

GotenbergConfig contient l’URL de l’API et, lorsque l’authentification est activée, un jeton bearer. Le champ du jeton est marqué #[\SensitiveParameter], il est donc masqué dans les traces d’appel. Tu restes responsable de sa provenance.

  • Récupère le jeton depuis ton gestionnaire de secrets ou depuis une variable d’environnement injectée au démarrage du processus. Ne le versionne pas, et ne le place pas dans un fichier de configuration livré dans l’image.
  • Construis la configuration une fois par portée de requête ou une fois par worker, pas à chaque conversion. Elle est immuable et peu coûteuse à conserver.
  • GotenbergConfig::fromArray() tolère par conception les entrées malformées : elle leur substitue silencieusement des valeurs par défaut. En production, valide toi-même le tableau source avant d’appeler fromArray(). Une URL manquante apparaît alors comme une erreur de configuration dans ton chemin de démarrage, plutôt que comme une exception Invalid Gotenberg configuration: apiUrl is empty survenant plus tard à chaque conversion.

timeout (en secondes, valeur par défaut 30) est le délai strict de transfert, appliqué par le transport épinglé à cURL. La conversion de documents Office via LibreOffice n’est pas instantanée ; les documents volumineux ou complexes prennent plus de temps. Définis le délai d’expiration à partir de la latence de conversion mesurée sur tes documents réels, avec une marge. Garde-le en deçà de toute passerelle en amont ou du max_execution_time de PHP. Ainsi, le délai de la passerelle est atteint en premier, et tu obtiens une exception typée au lieu d’un processus tué.

Si tu t’appuies sur le chemin du client PSR-18 injecté (aucune responseFactory injectée, ou une URL en IP brute sans épinglages), la passerelle n’impose pas la valeur timeout à ce client. Configure aussi le délai d’expiration sur le client PSR-18 lui-même, afin que les deux transports soient bornés.

La passerelle exécute exactement une requête par appel et ne réessaie jamais. Ajoute la logique de nouvelle tentative côté appelant, et rends-la sûre :

  • Ne réessaie qu’en cas de défaillance au niveau du transport (une GotenbergConvertException dont la cause est une exception du client PSR-18) et en cas d’erreurs serveur idempotentes (HTTP 502, 503, 504). Ne réessaie pas chaque GotenbergConvertException sans distinction. Une réponse de la classe 400 signifie généralement que l’entrée est incorrecte, et une nouvelle tentative échouera de la même manière.
  • Utilise un repli exponentiel borné avec gigue. Un service de conversion en surcharge renvoie 503 ; le marteler aggrave l’interruption.
  • Plafonne le nombre total de tentatives et le temps total écoulé. La conversion est déjà lente, donc des tentatives non bornées multiplient la latence de file d’attente.
  • La revalidation est automatique : chaque appel réessayé relance la validation de l’URL et la revérification de l’adresse, de sorte qu’une nouvelle tentative ne peut pas contourner accidentellement la protection SSRF.

Chaque conversion mobilise une connexion et un worker LibreOffice côté Gotenberg pendant toute la durée de la requête. La passerelle elle-même est sans état et peut être utilisée en toute sécurité depuis de nombreux workers en parallèle. Le service Gotenberg, en revanche, a une capacité de conversion limitée.

  • Borne de ton côté le nombre de conversions en cours (une file d’attente, un sémaphore ou un pool de workers) à la capacité que Gotenberg peut soutenir. Le dimensionnement est une propriété de ton déploiement Gotenberg, pas de ce paquet — voir /integrations/gotenberg/security-and-operations/.
  • Le plafond de taille d’entrée (maxFileSize, valeur par défaut 50 Mio) est la seule limite de ressources intégrée à la passerelle. Il est appliqué dans le processus avant l’envoi de la requête, de sorte qu’un fichier surdimensionné ne consomme jamais la capacité du service. Abaisse-le pour qu’il corresponde à ce dont tes documents ont réellement besoin ; un plafond plus bas est un contrôle anti-déni de service moins coûteux qu’un plafond plus élevé.
  • La passerelle n’effectue aucune mise en cache dans le processus. Si le même document est converti à plusieurs reprises, mets en cache le PDF résultant dans ton application, indexé par une empreinte de contenu de l’entrée.

Injecte un logger PSR-3 pour obtenir une entrée debug par requête de conversion. L’entrée contient l’URL de la requête, le nom du fichier, le format détecté et la longueur du contenu de la requête. Elle ne contient pas le contenu du fichier ni le jeton bearer.

  • Transforme ce signal en métriques : compte les conversions par format et par résultat, et enregistre le temps écoulé autour de chaque appel convertFile() / convertString() sous forme d’histogramme de latence. La passerelle n’émet pas elle-même de métriques.
  • L’objet résultat expose un champ renderTimeMs qui vaut 0.0 à moins que ton intégration ne le mesure et ne le renseigne ; la passerelle ne le remplit pas à partir de la réponse de Gotenberg. Chronomètre l’appel toi-même si tu as besoin de cette valeur.
  • Journalise les exceptions avec leur type. Le type de l’exception est le signal principal de ce qui a échoué ; le catalogue se trouve dans /integrations/gotenberg/troubleshooting/.
  • Sonde isAvailable() depuis ton point de terminaison de disponibilité ou de santé, pas à chaque conversion. Il s’agit d’un HEAD vers /health. L’exécuter avant chaque conversion double ton taux de requêtes vers le service sans aucun bénéfice.

La passerelle expose les défaillances sous forme d’exceptions typées et ne renvoie jamais de résultat partiel ou non validé. Les garanties pertinentes :

  • Un statut différent de 200, un Content-Type sans application/pdf, ou un corps qui ne commence pas par %PDF déclenchent chacun une GotenbergConvertException. Un objet résultat n’est renvoyé que lorsque ces trois vérifications réussissent.
  • Une défaillance du client PSR-18 (y compris une défaillance réseau ou un dépassement de délai) est encapsulée dans une GotenbergConvertException dont la cause est l’exception d’origine et dont le code d’exception reprend celui du client.
  • Les échecs de validation (URL non HTTPS, adresse private/reserved, entrée surdimensionnée, nom de fichier non sûr) déclenchent une RuntimeException avant tout trafic réseau.
  • Une extension de fichier non reconnue déclenche une ValueError avant tout trafic réseau.

Capture les types spécifiques. Le programme d’exemple dans examples/convert-office-to-pdf.php montre l’ordre de capture exhaustif. /integrations/gotenberg/troubleshooting/ explique chaque déclencheur.

La passerelle produit un PDF puis s’arrête. Un pipeline de production courant est le suivant :

  1. Convertir le document Office avec cette passerelle.
  2. Charger les octets résultants dans un document NextPDF.
  3. Appliquer le post-traitement — assemblage de pages, filigrane, conversion PDF/A, signatures numériques.

L’étape 3 relève de la responsabilité de NextPDF, pas de celle de la passerelle. La signature, les profils PDF/A et le filigrane sont fournis par nextpdf/premium. Garde la conversion et le post-traitement comme des étapes distinctes, afin qu’un échec de conversion et un échec de signature puissent être diagnostiqués indépendamment.

La prise en charge PAdES de l’édition Pro se limite au niveau de référence B-B. Elle ne fournit pas B-T, B-LT ni B-LTA, et ces profils ne découlent pas de la conversion d’un document via cette passerelle. La capacité de validation à long terme relève d’une édition distincte et est hors du périmètre de ce paquet.

  • /integrations/gotenberg/configuration/ — les règles de sélection du transport et le modèle d’épinglage.
  • /integrations/gotenberg/security-and-operations/ — déployer et durcir la dépendance Gotenberg.
  • /integrations/gotenberg/troubleshooting/ — le catalogue des exceptions.
  • /integrations/gotenberg/integration/ — relier le PDF converti à un pipeline NextPDF.