دليل النشر

استضافة Gotenberg على VPS: واجهة توليد PDF للمطورين

انشر على VPS Cloud ←

دليل عملي

التطوير

استضافة Gotenberg على VPS: واجهة توليد PDF للمطورين

كل خدمة PDF كـ SaaS تُحاسب لكل صفحة أو مستند. Gotenberg لا تفعل ذلك — إنها خدمة HTTP مصغّرة مفتوحة المصدر برخصة MIT تُولّد PDF من HTML والروابط وMarkdown ومستندات LibreOffice، مع تضمين ‎Chromium وLibreOffice في حاوية Docker واحدة. يغطي هذا الدليل النشر الكامل على VPS — مسارات API ووكيل nginx العكسي وأمثلة تكامل PHP/Python/Node.js والإعداد المتقدم وتشخيص الأخطاء الشائعة.

8 دقائق للقراءةعدد الخطوات: 5
المحتويات· لماذا استضافة واجهة API لتوليد PDF ذاتيًا؟1/11
  1. 01لماذا استضافة واجهة API لتوليد PDF ذاتيًا؟
  2. 02Gotenberg أم WeasyPrint أم Stirling-PDF أم Puppeteer؟
  3. 03ما يمكن لـ Gotenberg تحويله
  4. 04المتطلبات
  5. 05نشر Gotenberg خطوة بخطوة
  6. 06مسارات API وصيغها
  7. 07وكيل nginx العكسي
  8. 08التكامل المتقدم: PHP وPython وNode.js
  9. 09الإعداد المتقدم
  10. 10تشخيص الأخطاء الشائعة
  11. 11التكامل مع تطبيقك

لماذا استضافة واجهة API لتوليد PDF ذاتيًا؟

خدمات PDF كـ SaaS تُحاسب لكل مستند أو صفحة أو استدعاء API. بمجرد أن يُولّد تطبيقك فواتير أو تقارير أو عقودًا بكميات كبيرة، تنمو التكلفة خطيًا مع استخدامك. Gotenberg تستبدلها بتكلفة VPS شهرية ثابتة بصرف النظر عن عدد PDF التي تُولّدها. كما تبقي مستنداتك خاصة: لا شيء يغادر بنيتك التحتية أثناء التحويل.

Gotenberg أم WeasyPrint أم Stirling-PDF أم Puppeteer؟

مرّر الجدول أفقيًا

الأداةصيغ المصدرالحد الأدنى من RAMواجهة RESTالرخصة
Gotenberg 8.xHTML، URL، DOCX/ODT/XLSX، Markdown، صور‎2 GB (Chromium)نعم — multipart/form-dataMIT
WeasyPrintHTML + CSS (بدون JS)‎256 MBلا — مكتبة Python/CLIBSD
Stirling-PDFPDF (تحرير، OCR، دمج)‎512 MBنعم — JSON/multipartMIT (AGPLv3 للنسخة Pro)
Puppeteer منفردًاHTML + URL عبر Chrome headless‎1.5 GBلا — مكتبة Node.jsApache 2.0

ما يمكن لـ Gotenberg تحويله

  • HTML إلى PDF عبر نسخة Chromium كاملة — CSS وخطوط الويب وJavaScript واستفسارات وسائط الطباعة مُكرَّمة جميعها.
  • أي رابط إلى PDF — أرشف مشاهدات لوحة التحكم وأنشئ تقارير أسبوعية أو التقط إيصالات الدفع.
  • مستندات LibreOffice (DOCX وXLSX وPPTX وODT وODS وODP وأكثر من 20 صيغة) إلى PDF بدون تثبيت Microsoft Office.
  • Markdown إلى PDF عبر مسار Chromium مع CSS قابل للتهيئة.
  • دمج عدة ملفات PDF في ملف واحد باستدعاء API واحد.
  • الصور (PNG وJPEG وWebP وTIFF) محوَّلة إلى PDF.

المتطلبات

خادم VPS بـ ‎1 vCPU على الأقل و‎2 GB RAM (يستهلك Chromium وحده من 1.2 إلى 1.5 GB أثناء التصيير؛ 1 GB RAM غير كافٍ أثناء التحويل). Ubuntu 22.04 أو 24.04 مع Docker وDocker Compose v2 مثبَّتَين. يستمع Gotenberg على المنفذ 3000 افتراضيًا. لا يلزم نطاق إذا استدعيت الواجهة API من نفس الخادم — http://127.0.0.1:3000 يكفي. لكشفه لخدمات أخرى يُوصى بوكيل nginx العكسي (انظر أدناه).

نشر Gotenberg خطوة بخطوة

  1. إنشاء ملف compose

    اتصل بـ VPS عبر SSH وأنشئ مجلدًا:

    mkdir gotenberg && cd gotenberg

    أنشئ 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

    الربط بـ 127.0.0.1 يمنع الوصول المباشر من الإنترنت. في عام 2026 الإصدار المستقر هو 8.x (8.9.1 فما فوق) — الصورة :8 تتبع أحدث 8.x.

  2. تشغيل الحاوية

    شغّل docker compose up -d. يسحب Gotenberg الصورة (~1.5 GB، تشمل Chromium وLibreOffice) ويشغّل خادم HTTP. تحقق من نقطة نهاية الصحة:

    curl http://127.0.0.1:3000/health

    aستجابة {"status":"up"} تؤكد أن الخدمة جاهزة.

  3. توليد أول PDF من HTML

    أنشئ ملف HTML بسيطًا (invoice.html) وحوّله:

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

    الاستجابة هي PDF كتدفق ثنائي.

  4. تحويل مستند Word إلى PDF

    ارفع ملف DOCX إلى مسار LibreOffice:

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

    يستخدم Gotenberg محرك LibreOffice المدمج للتحويل — لا يلزم ترخيص Microsoft Office.

  5. إضافة المصادقة (مستحسن)

    ليس لدى Gotenberg مصادقة مدمجة. النهج المستحسن: ثبّت nginx، أنشئ وكيلًا عكسيًا من https://gotenberg.your-domain.com إلى http://127.0.0.1:3000، وأضف مصادقة HTTP basic. لا تكشف الخدمة أبدًا دون مصادقة على الإنترنت العام.

مسارات API وصيغها

يكشف Gotenberg عائلتين من مسارات REST، جميعها POST multipart/form-data.

مسارات Chromium — التصيير عبر متصفح headless:
- POST /forms/chromium/convert/html — التحويل من ملف HTML محلي (حقل index.html).
- POST /forms/chromium/convert/url — التحويل من رابط عام (حقل url)؛ يحمّل Chromium الصفحة كاملة بما فيها JavaScript.
- POST /forms/chromium/convert/markdown — تحويل Markdown مع ورقة أنماط اختيارية.

مسارات LibreOffice — تحويل مستندات المكتب:
- POST /forms/libreoffice/convert — يقبل DOCX وXLSX وPPTX وODT وODS وODP وأكثر من 20 صيغة؛ يدمج عدة ملفات في PDF واحد إذا أرسلت merge=true.

مسارات PDF — معالجة PDF الموجودة:
- POST /forms/pdfengines/merge — يدمج عدة ملفات PDF في ملف واحد.
- POST /forms/pdfengines/convert — يحوّل إلى PDF/A (أرشفة طويلة المدى).

Webhook: بدلًا من تلقي PDF ردًا متزامنًا، مرّر ترويسة Gotenberg-Webhook-Url — سيُرسل Gotenberg PDF إلى عنوانك URL بمجرد انتهاء التحويل.

وكيل nginx العكسي

لكشف Gotenberg لخدمات أخرى أو استدعائه من نطاق مخصص، أضف كتلة location في إعداد nginx:

server {
    listen 443 ssl;
    server_name gotenberg.your-domain.com;

    ssl_certificate     /etc/letsencrypt/live/gotenberg.your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/gotenberg.your-domain.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;
        client_max_body_size 50M;

        auth_basic           "Gotenberg API";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }
}

إذا كان Gotenberg يعمل على نفس الخادم مع تطبيقك الخلفي، فضّل الاستدعاء المباشر على http://127.0.0.1:3000 — يتجنب حركة الشبكة الخارجية ولا يتطلب كشف الخدمة على نطاق.

التكامل المتقدم: PHP وPython وNode.js

Gotenberg محايد للغة — أي عميل HTTP قادر على إرسال multipart/form-data يعمل.

PHP / Laravel — استخدم حزمة gotenberg-php الرسمية:

use Gotenberg\Gotenberg;
use Gotenberg\Stream;

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

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

Python — مع مكتبة 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('invoice.html'))
        response = route.run()
        Path('invoice.pdf').write_bytes(response.content)

Node.js — مع fetch الأصلي (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('invoice.pdf', pdf);

الإعداد المتقدم

تُمرَّر المعاملات كوسائط لأمر gotenberg في docker-compose.yml (أو عبر متغيرات بيئة بالبادئة GOTENBERG_).

المهلة: --api-timeout=30s — المدة القصوى لتحويل. زدها (مثلًا 60s) لمستندات DOCX الطويلة أو الصفحات ذات JavaScript الثقيل.

التزامن: --chromium-max-queue-size=10 — الحد الأقصى للتحويلات في قائمة الانتظار. عند تجاوزه يرد Gotenberg بـ 503 بدلًا من التراكم في الذاكرة.

تسجيل الأحداث: يسجّل Gotenberg بصيغة JSON على stdout — docker compose logs gotenberg يمنحك تفاصيل كل تحويل.

تعطيل LibreOffice (إذا احتجت Chromium فقط، توفيرًا في RAM):

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

للبنى عالية الحجم، شغّل عدة نسخ من Gotenberg خلف موازن حمل nginx (upstream): تحتفظ كل نسخة بعمالها من Chromium، وتتوسع أفقيًا دون حالة مشتركة.

تشخيص الأخطاء الشائعة

مهلة Chromium — context deadline exceeded: يتجاوز تحويل HTML المهلة المضبوطة. الأسباب الشائعة: JavaScript بطيء، موارد خارجية (CDN، خطوط Google Fonts) غير متاحة من الخادم، أو DOM ضخم جدًا. الحل: زد --api-timeout، استضف أصولك محليًا وألحقها كحقول multipart.

المنفذ 3000 مشغول: تطبيق آخر يستمع على 3000. عدّل التعيين في docker-compose.yml: "127.0.0.1:3001:3000" وحدّث الرابط URL في استدعاءاتك.

الملف كبير جدًا — 413 Request Entity Too Large: يقطع nginx الطلب قبل Gotenberg. زد client_max_body_size في كتلة nginx (مثلًا 100M لملفات XLSX الكبيرة).

نفاد الذاكرة — OOMKilled: يقتل Docker الحاوية عندما يتجاوز Chromium RAM المتاحة. تحقق بـ docker inspect gotenberg | grep OOMKilled. الحلول: أضف RAM لـ VPS، قلّل التزامن (--chromium-max-queue-size=3), أو عطّل JavaScript إذا لم يحتجه HTML.

خطأ LibreOffice — ملف تالف أو صيغة غير معترف بها: بعض ملفات DOCX من أدوات طرف ثالث غير متوافقة مع معيار OOXML. تحقق أولًا أن الملف يفتح بدون أخطاء في LibreOffice Desktop. يعطيك ترويسة سجل Gotenberg رسالة LibreOffice الدقيقة (docker compose logs gotenberg --tail 50).

التكامل مع تطبيقك

Gotenberg محايد للغة — أي عميل HTTP يعمل. توجد مكتبات لـ PHP و‎Node.js وPython وGo وغيرها. لـ Laravel توجد حزمة رسمية تُغلّف الواجهة API. في Node.js يمكنك استدعاؤها بـ axios أو fetch الأصلية بإرسال كائن FormData مع محتوى HTML أو الملف. راجع قسم التكامل المتقدم أعلاه لأمثلة كود جاهزة بكل لغة.

انشر Gotenberg على VPS Cloud من ServOrbit في دقائق

مع VPS Cloud من ServOrbit تحصل على Docker مُهيأ مسبقًا وRAM قابلة للتوسع — القاعدة الصحيحة لـ Gotenberg للتعامل مع تصيير Chromium وتحويل LibreOffice بدون تنازع على الموارد.