Guide de déploiement

Héberger Gotenberg sur un VPS : API PDF pour développeurs

Déployer sur un VPS Cloud →

Tutoriel

Développement

Héberger Gotenberg sur un VPS : API PDF pour développeurs

Chaque service PDF SaaS facture à la page ou au document. Gotenberg, non. C'est un microservice HTTP open source sous licence MIT qui génère des PDF depuis HTML, URLs, Markdown et documents LibreOffice, avec Chromium et LibreOffice intégrés dans un seul conteneur Docker. Ce guide couvre le déploiement complet sur un VPS — routes d'API, reverse proxy nginx, exemples d'intégration PHP/Python/Node.js, configuration avancée et dépannage des erreurs courantes.

8 min de lecture5 étapes
Sommaire· Pourquoi auto-héberger une API de génération PDF ?1/11
  1. 01Pourquoi auto-héberger une API de génération PDF ?
  2. 02Gotenberg, WeasyPrint, Stirling-PDF ou Puppeteer ?
  3. 03Ce que Gotenberg peut convertir
  4. 04Prérequis
  5. 05Déployer Gotenberg étape par étape
  6. 06Routes et formats de l'API
  7. 07Reverse proxy nginx
  8. 08Intégration avancée : PHP, Python, Node.js
  9. 09Configuration avancée
  10. 10Dépannage des erreurs courantes
  11. 11Intégrer avec votre application

Pourquoi auto-héberger une API de génération PDF ?

Les services PDF SaaS (Puppeteer Cloud, PDFShift, DocRaptor) facturent par document, par page ou par volume d'appels API. Dès que votre application génère des factures, rapports ou contrats à l'échelle, le coût augmente linéairement avec votre usage. Gotenberg les remplace par un coût VPS mensuel fixe, quel que soit le nombre de PDF générés. Il préserve également la confidentialité de vos documents : rien ne quitte votre infrastructure pendant la conversion.

Gotenberg, WeasyPrint, Stirling-PDF ou Puppeteer ?

Faites défiler le tableau

OutilFormats sourcesRAM minAPI RESTLicence
Gotenberg 8.xHTML, URL, DOCX/ODT/XLSX, Markdown, images2 Go (Chromium)Oui — multipart/form-dataMIT
WeasyPrintHTML + CSS (pas JS)256 MoNon — lib Python/CLIBSD
Stirling-PDFPDF (édition, OCR, fusion)512 MoOui — JSON/multipartMIT (AGPLv3 pour Pro)
Puppeteer seulHTML + URL via headless Chrome1,5 GoNon — lib Node.jsApache 2.0

Ce que Gotenberg peut convertir

  • HTML vers PDF via une instance Chromium complète — CSS, polices web, JavaScript et media queries d'impression sont tous honorés.
  • N'importe quelle URL vers PDF — archivez des vues de tableau de bord, générez des rapports hebdomadaires ou capturez des reçus de paiement.
  • Documents LibreOffice (DOCX, XLSX, PPTX, ODT, ODS, ODP et 20+ formats) vers PDF sans Microsoft Office.
  • Markdown vers PDF via la route Chromium avec CSS configurable.
  • Plusieurs PDF fusionnés en un seul fichier en un appel API.
  • Images (PNG, JPEG, WebP, TIFF) converties en PDF.

Prérequis

Un VPS avec au moins 1 vCPU et 2 Go de RAM (Chromium seul consomme 1,2 à 1,5 Go au rendu ; 1 Go de RAM est insuffisant dès qu'une conversion est en cours). Ubuntu 22.04 ou 24.04 avec Docker et Docker Compose v2 installés. Gotenberg écoute sur le port 3000 par défaut. Aucun domaine n'est nécessaire si vous appelez l'API depuis le même serveur — http://127.0.0.1:3000 suffit. Pour l'exposer à d'autres services, un reverse proxy nginx est recommandé (voir plus bas).

Déployer Gotenberg étape par étape

  1. Créer le fichier compose

    Connectez-vous en SSH à votre VPS et créez un répertoire :

    mkdir gotenberg && cd gotenberg

    Créez docker-compose.yml :

    services:
      gotenberg:
        image: gotenberg/gotenberg:8
        restart: unless-stopped
        ports:
          - "127.0.0.1:3000:3000"
        command:
          - gotenberg
          - --chromium-disable-javascript=false
          - --api-timeout=30s
          - --chromium-max-queue-size=10

    La liaison à 127.0.0.1 empêche l'accès direct depuis Internet. Au 2026, la version stable est 8.x (8.9.1 et supérieures) — l'image :8 suit la dernière 8.x.

  2. Démarrer le conteneur

    Exécutez docker compose up -d. Gotenberg tire l'image (~1,5 Go, inclut Chromium et LibreOffice) et démarre le serveur HTTP. Vérifiez l'endpoint de santé :

    curl http://127.0.0.1:3000/health

    Une réponse {"status":"up"} confirme que le service est prêt.

  3. Générer votre premier PDF depuis HTML

    Créez un fichier HTML minimal (facture.html) et convertissez-le :

    curl -s --request POST http://127.0.0.1:3000/forms/chromium/convert/html \
      --form '[email protected]' \
      -o facture.pdf

    La réponse est le PDF en flux binaire — redirigez-le vers un fichier, un objet réponse ou un upload S3.

  4. Convertir un document Word en PDF

    Téléversez un fichier DOCX vers la route LibreOffice :

    curl -s --request POST http://127.0.0.1:3000/forms/libreoffice/convert \
      --form '[email protected]' \
      -o contrat.pdf

    Gotenberg utilise le moteur LibreOffice intégré pour la conversion — aucune licence Microsoft Office requise.

  5. Ajouter une authentification (recommandé)

    Gotenberg n'a pas d'authentification intégrée. L'approche recommandée : installez nginx, créez un reverse proxy de https://gotenberg.votre-domaine.com vers http://127.0.0.1:3000, et ajoutez une authentification HTTP basic. Seul le backend de votre application devrait appeler cet endpoint — ne l'exposez jamais sans authentification à Internet public, car il peut être utilisé pour rendre des URLs arbitraires.

Routes et formats de l'API

Gotenberg expose deux familles de routes REST, toutes en POST multipart/form-data.

Routes Chromium — rendu via un navigateur headless :
- POST /forms/chromium/convert/html — conversion depuis un fichier HTML local (champ index.html) ; les assets CSS/JS/images peuvent être joints en champs supplémentaires.
- POST /forms/chromium/convert/url — conversion depuis une URL publique (champ url) ; Chromium charge la page entière, JavaScript compris.
- POST /forms/chromium/convert/markdown — conversion Markdown avec feuille de style optionnelle.

Routes LibreOffice — conversion de documents bureautiques :
- POST /forms/libreoffice/convert — accepte DOCX, XLSX, PPTX, ODT, ODS, ODP et 20+ formats ; plusieurs fichiers convertis en un seul PDF si vous envoyez merge=true.

Route PDF — manipulation de PDF existants :
- POST /forms/pdfengines/merge — fusionne plusieurs fichiers PDF en un seul.
- POST /forms/pdfengines/convert — conversion vers PDF/A (archivage long terme).

Webhook : au lieu de recevoir le PDF en réponse synchrone, vous pouvez passer un header Gotenberg-Webhook-Url — Gotenberg envoie alors le PDF en POST vers votre URL dès la conversion terminée, libérant la connexion cliente immédiatement. Utile pour les conversions longues ou les architectures asynchrones.

Reverse proxy nginx

Pour exposer Gotenberg à d'autres services ou l'appeler depuis un domaine dédié, ajoutez un bloc location dans votre configuration nginx :

server {
    listen 443 ssl;
    server_name gotenberg.votre-domaine.com;

    # TLS via certbot ou votre CA
    ssl_certificate     /etc/letsencrypt/live/gotenberg.votre-domaine.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/gotenberg.votre-domaine.com/privkey.pem;

    location / {
        proxy_pass         http://127.0.0.1:3000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_read_timeout 60s;   # laisser le temps à Chromium de rendre
        client_max_body_size 50M; # pour les gros DOCX/XLSX

        # Authentification HTTP basic
        auth_basic           "Gotenberg API";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }
}

Si Gotenberg tourne sur le même serveur que votre application backend, préférez l'appel direct sur http://127.0.0.1:3000 sans passer par nginx — moins de latence et pas besoin d'exposer le service sur un domaine.

Intégration avancée : PHP, Python, Node.js

Gotenberg est indépendant du langage — tout client HTTP capable d'envoyer du multipart/form-data fonctionne.

PHP / Laravel — utilisez le package officiel gotenberg-php :

use Gotenberg\Gotenberg;
use Gotenberg\Stream;

$request = Gotenberg::chromium('http://127.0.0.1:3000')
    ->pdf()
    ->html(Stream::path('/chemin/vers/facture.html'));

$response = $client->sendRequest($request);
file_put_contents('facture.pdf', $response->getBody());

Python — avec la bibliothèque gotenberg-client :

from gotenberg_client import GotenbergClient

with GotenbergClient('http://127.0.0.1:3000') as client:
    with client.chromium.html_to_pdf() as route:
        route.index(Path('facture.html'))
        response = route.run()
        Path('facture.pdf').write_bytes(response.content)

Node.js — avec fetch natif (Node 18+) :

const form = new FormData();
form.append('index.html', new Blob([htmlContent], { type: 'text/html' }), 'index.html');

const res = await fetch('http://127.0.0.1:3000/forms/chromium/convert/html', {
  method: 'POST',
  body: form,
});
const pdf = Buffer.from(await res.arrayBuffer());
fs.writeFileSync('facture.pdf', pdf);

Pour Node.js, le package chromiumly encapsule l'API complète si vous préférez éviter le FormData manuel.

Configuration avancée

Les paramètres se passent en arguments de la commande gotenberg dans votre docker-compose.yml (ou via variables d'environnement préfixées GOTENBERG_).

Timeout : --api-timeout=30s — durée maximale d'une conversion. Augmentez-le (ex. 60s) si vous convertissez de longs documents DOCX ou des pages avec beaucoup de JavaScript.

Concurrence : --chromium-max-queue-size=10 — nombre maximum de conversions Chromium en file. Au-delà, Gotenberg répond 503 plutôt que d'accumuler en mémoire. Ajustez selon votre RAM disponible (chaque conversion Chromium ouvre une instance éphémère).

Rate limit : --api-port-from-env combiné à un reverse proxy nginx (limit_req_zone) constitue la solution recommandée pour limiter les appels entrants.

Logs : Gotenberg logue en JSON sur stdout — docker compose logs gotenberg vous donne le détail de chaque conversion (durée, route, statut). Pour un log plus verbeux :

command:
  - gotenberg
  - --log-level=debug

Désactiver LibreOffice (si vous n'avez besoin que de Chromium, économie de RAM) :

command:
  - gotenberg
  - --libreoffice-disable-listener=true

Pour les architectures à fort volume, lancez plusieurs répliques Gotenberg derrière un équilibreur de charge nginx (upstream) : chaque instance tient ses propres workers Chromium, et vous scalez horizontalement sans partager d'état.

Dépannage des erreurs courantes

Timeout Chromium — context deadline exceeded : la conversion HTML dépasse le timeout configuré. Causes fréquentes : page avec JavaScript lent, ressources externes (CDN, polices Google Fonts) inaccessibles depuis le serveur, ou DOM trop volumineux. Solution : augmentez --api-timeout, hébergez vos assets localement et joignez-les en champs du formulaire multipart plutôt que de les charger par URL.

Port 3000 déjà occupé : une autre application écoute sur 3000. Modifiez le mapping dans docker-compose.yml : "127.0.0.1:3001:3000" et mettez à jour l'URL dans vos appels.

Fichier trop grand — 413 Request Entity Too Large : nginx coupe la requête avant Gotenberg. Augmentez client_max_body_size dans le bloc nginx (ex. 100M pour les gros XLSX).

Mémoire insuffisante — OOMKilled : Docker tue le conteneur quand Chromium dépasse la RAM disponible. Vérifiez docker inspect gotenberg | grep OOMKilled. Remèdes : ajouter de la RAM au VPS, limiter la concurrence (--chromium-max-queue-size=3), ou désactiver JavaScript si votre HTML ne le requiert pas (--chromium-disable-javascript=true).

Erreur LibreOffice — fichier corrompu ou format non reconnu : certains DOCX générés par des outils tiers ne sont pas conformes au standard OOXML. Vérifiez d'abord que le fichier s'ouvre sans erreur dans LibreOffice Desktop. L'en-tête de log Gotenberg indique le message LibreOffice exact (docker compose logs gotenberg --tail 50).

Intégrer avec votre application

Gotenberg est indépendant du langage — tout client HTTP fonctionne. Des bibliothèques existent pour PHP (gotenberg-php), Node.js (chromiumly), Python (gotenberg-client), Go et d'autres. Pour Laravel, un package officiel encapsule l'API. En Node.js, vous pouvez l'appeler avec axios ou l'API fetch native en envoyant un objet FormData avec le contenu HTML ou le fichier. Consultez la section « Intégration avancée » ci-dessus pour des exemples de code prêts à l'emploi dans chaque langage.

Déployez Gotenberg en quelques minutes sur un VPS Cloud ServOrbit

Avec un VPS Cloud ServOrbit doté de Docker préconfiguré et de ressources évolutives, vous installez Gotenberg et obtenez une API de génération PDF privée pour tous vos backends sans facturation à la requête.