Journal indexDockup / field note
Note / self-host-gotenberg

How to Self-Host Gotenberg in 2026: HTML-to-PDF, Timeouts and Fonts

Deploy Gotenberg with the right port, durable storage, TLS, authentication and backups. Troubleshoot when requests use the wrong multipart field in production.

A failed Gotenberg deployment does not always crash. It may serve a login page while requests use the wrong multipart field or conversions exceed proxy timeouts. Start with an end-to-end check instead: post HTML and assets as multipart data, render a PDF, repeat with an Office document and inspect the health endpoint after each conversion.

That check matches the cataloged purpose of Gotenberg: HTTP service that converts HTML, Markdown and Office files to PDF. It also exposes missing dependencies, wrong proxy assumptions and ephemeral data earlier than an uptime probe can.

Ports, processes and private services

Do not let the Gotenberg image choose production architecture by accident. The image supplies a process on 3000; storage, routing and external requirements still need deliberate lifecycles. The local runtime requirement is CPU and memory headroom for Chromium and LibreOffice workers. Test that boundary before publication and again after a container replacement.

The deployment is ready for deeper testing when it can post HTML and assets as multipart data, render a PDF, repeat with an Office document and inspect the health endpoint after each conversion. Follow the transaction in logs and watch Chromium and LibreOffice process count, temporary disk, document complexity and proxy timeouts. Those observations reveal whether the current topology isolates the right component.

Make Gotenberg recovery measurable

No writable application state is expected inside the standard Gotenberg image. Preserve no durable app data; retain fonts, templates and deployment configuration, including the pinned digest and reviewed route configuration, rather than backing up an empty container filesystem.

Create Gotenberg from scratch on another host and verify that custom fonts, templates and command flags are reproducible and known documents render with expected page counts. If a separate database, room server or authentication layer is added, give that component its own explicit recovery owner. The Git-to-production guide shows how a reproducible artifact replaces a container backup.

Record the rebuild command and known-output test with the release. A stateless recovery plan succeeds by reproducing behavior from trusted inputs; it should not depend on copying an opaque running container.

Reduce the authority held by Gotenberg

The valuable asset in Gotenberg is the code path that handles user input. Its application-specific risk is allowing unrestricted public conversions without size and timeout controls; production should keep conversion endpoints private or enforce size, rate and timeout controls before allowing untrusted files.

The standard container has no administrator secret, so authentication belongs at the HTTPS route if the service is private. Pin the build, avoid broad filesystem mounts and constrain Chromium and LibreOffice process count, temporary disk, document complexity and proxy timeouts. Use known test input to confirm that the served build produces expected output after every update.

The Gotenberg release gate

Convert the Gotenberg smoke test into a repeatable release command or short runbook. Its output must demonstrate this outcome: post HTML and assets as multipart data, render a PDF, repeat with an Office document and inspect the health endpoint after each conversion. Record the application version, container digest, route hostname and test-data identifier with the result.

Run the same check after a routine container swap and after restoring no durable app data; retain fonts, templates and deployment configuration elsewhere. The restore has succeeded when custom fonts, templates and command flags are reproducible and known documents render with expected page counts. Compare timing and consumption related to Chromium and LibreOffice process count, temporary disk, document complexity and proxy timeouts; a large change is worth investigation even when the final action still passes.

Then exercise a safe failure: submit harmless input near the resource or format limit associated with this boundary: requests use the wrong multipart field or conversions exceed proxy timeouts. Confirm that Gotenberg surfaces the fault and returns to normal without destructive manual edits. Preserve only the necessary, redacted log excerpt. This four-part gate covers startup, persistence, recovery and failure handling.

Make Gotenberg startup reproducible

Use a command that exposes every important choice. This baseline binds Gotenberg to host loopback, adds the known data mounts and supplies the first required setting. Confirm the local requirement before exposure: CPU and memory headroom for Chromium and LibreOffice workers.

docker run -d \
  --name gotenberg \
  --restart unless-stopped \
  -p 127.0.0.1:3000:3000 \
  gotenberg/gotenberg:8

Replace floating tags with a tested version or digest. After startup, inspect docker logs --tail 200 gotenberg and confirm the process listens on 3000. Then execute the Gotenberg acceptance action; a root-page response cannot prove the full scenario succeeds: post HTML and assets as multipart data, render a PDF, repeat with an Office document and inspect the health endpoint after each conversion.

Prevent proxy success from masking application failure

Choose the final Gotenberg hostname before users save callbacks or client settings, then expose the conversion API through HTTPS or a private internal domain. The platform route should terminate TLS once and target private port 3000.

Run the acceptance transaction externally. If the client never reaches Gotenberg, use the SSL validation checklist for DNS and certificate checks. If the request reaches Gotenberg but requests use the wrong multipart field or conversions exceed proxy timeouts, stop changing proxy redirects and inspect the application-specific boundary instead.

Capacity and upgrade checks

The useful service indicator for Gotenberg is successful completion of “post HTML and assets as multipart data, render a PDF, repeat with an Office document and inspect the health endpoint after each conversion”. Pair that result with Chromium and LibreOffice process count, temporary disk, document complexity and proxy timeouts; a green root page says nothing about output compatibility or resource exhaustion.

Before replacing the image, account for this risk: API routes, Chromium flags and LibreOffice behavior may change across major Gotenberg versions. Test representative and boundary inputs against both versions and retain the old digest until the candidate passes. If requests use the wrong multipart field or conversions exceed proxy timeouts, inspect the request format, client behavior and runtime logs before changing route or storage settings.

Where Dockup removes work for Gotenberg

A one-click Gotenberg template should encode the image digest, port 3000, health timing, domain and TLS. Because the base service is stateless, Dockup can recreate it directly on Dockup compute or an attached machine without pretending an empty volume is a backup.

After launch, Expose the conversion API through HTTPS or a private internal domain. Dockup should preserve the Gotenberg runtime settings while the operator confirms this local requirement: CPU and memory headroom for Chromium and LibreOffice workers. Verify this outcome: post HTML and assets as multipart data, render a PDF, repeat with an Office document and inspect the health endpoint after each conversion. Any later stateful extension must declare its own mount, secret and restore test rather than changing the meaning of the base template silently.

Frequently asked questions

What does Gotenberg need for a production deployment?

Route the Gotenberg container on port 3000 through one HTTPS origin. The local runtime requirement is CPU and memory headroom for Chromium and LibreOffice workers. Do not call Gotenberg ready until you can post HTML and assets as multipart data, render a PDF, repeat with an Office document and inspect the health endpoint after each conversion.

Which Gotenberg data belongs in a backup?

The standard Gotenberg image has no required application-data mount. Preserve its deployment configuration and back up any connected state separately; recovery passes when custom fonts, templates and command flags are reproducible and known documents render with expected page counts.

Does Gotenberg require HTTPS behind a reverse proxy?

Use HTTPS for the public Gotenberg origin and keep port 3000 on the internal route. Apply the Gotenberg setting correctly: expose the conversion API through HTTPS or a private internal domain. For Gotenberg, HTTPS protects credentials or user content in transit and keeps origin-sensitive client behavior consistent.

How should a Gotenberg upgrade be tested?

Deploy the candidate Gotenberg image beside the current one and repeat the acceptance transaction with known input. Pay particular attention because API routes, Chromium flags and LibreOffice behavior may change across major Gotenberg versions. The standard container has no data migration, so retain the previous digest until output and compatibility checks pass.