Update docker.io/gotenberg/gotenberg Docker tag to v9 #186
No reviewers
Labels
No labels
bug
duplicate
enhancement
help wanted
host: grafana
host: netbox
invalid
question
renovate
waiting on upstream
wontfix
No milestone
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
CCCHH/ansible-infra!186
Loading…
Reference in a new issue
No description provided.
Delete branch "renovate/docker.io-gotenberg-gotenberg-9.x"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR contains the following updates:
8.38.1→9.0.0Release Notes
gotenberg/gotenberg (docker.io/gotenberg/gotenberg)
v9.0.0: 9.0.0Compare Source
Gotenberg 9 is out 🎉
One PDF engine
pdfcpu, QPDF, pdftk and ExifTool are replaced by litho, a PDF engine written in Go for Gotenberg, running in-process.
remediaterepairs a PDF until it conforms to one of the eleven PDF/A levels, to PDF/UA-1 or PDF/UA-2, to both together, or to Factur-X, then checks its own result:Gotenberg-Remediation-Residualcounts the violations left,Gotenberg-Remediation-Rolled-Backthe fixes undone to keep pages, text and images./forms/pdf/validateruns the same checks on any PDF.litho also signs and timestamps, redacts from the file rather than from view, infers a structure tree, renders pages as images, fills and flattens forms in the scripts the image's fonts cover, and shrinks a PDF without touching image quality. A stage that would drop the signatures of a signed PDF answers
400, as does text no font can draw.Stages, in your order
Post-processing is no longer flat fields in a fixed order. A
stageslist runs as written, on every route that makes a PDF and on/forms/pdf/pipefor PDFs you already have:26 stages, each also a
/forms/pdf/<op>route with form fields, plus six JSON read routes: info, validation, metadata, bookmarks, attachments and form fields. A broken order answers400before anything runs.LibreOffice through lok
unoconverter, Python and the
sofficelistener are replaced by lok, a long-running LibreOfficeKit process that Gotenberg supervises and restarts after a crash. Macros stay off;--libreoffice-enable-macrosruns them.Fewer dependencies, less CVE surface
Java, Python, unoconverter, pdfcpu, QPDF, pdftk and ExifTool leave the image: fewer packages to patch, and no more CVE reports about tools Gotenberg does not ship. Variants, architectures, user, port and command don't change.
Upgrading
Start from the upgrade guide.
/forms/pdfenginesroutes become/forms/pdfroutes, post-processing fields become stages, and a field with a stage twin now starts withnative. A removed route answers404naming its replacement, a Gotenberg 8 field400saying where it went:Custom builds import
github.com/gotenberg/gotenberg/v9. ThePdfEngine,PdfEngineProviderandMetricsProviderinterfaces and the Prometheus module are gone:OTEL_METRICS_EXPORTER=prometheusserves the same.Everything else
PDF
set-formselects several list items, refuses a value a field cannot hold, and lists the PDF's fields when you name a missing one.flatten-formdraws a value without appearance over the field's own background and border.400naming the characters.optimizepacks objects into compressed streams, stores identical streams once, recompresses images losslessly and subsets fonts. Every pass runs unless turned off. An encrypted input needs adecryptorencryptstage first.mergekeeps each file's bookmarks, remapped, and names the result after the first file in alphanumeric order.renderdraws pages as PNG or JPEG at the resolution you ask.--pdf-max-stream-bytes,--pdf-max-embedded-file-bytesand--pdf-max-image-pixelsbound what litho reads.--pdf-allow-list,--pdf-deny-listand their siblings filter the timestamp authorities it calls.LibreOffice
nativePdfatakesPDF/A-1b,PDF/A-2b,PDF/A-3borPDF/A-4;nativePdfuatakesPDF/UA-1. The PDF/A export is no longer redone after the other steps: end the stages withremediatewhen they may break conformance.initialView,magnificationandpageLayouttake names such asoutlineorfitWidth, not numbers.firstPageOnLeft, which LibreOffice ignored, andnativePdfFormatsare gone.nativeWatermarkColortakes#rrggbb,nativeWatermarkRotationdegrees counter-clockwise,0being horizontal. A plain and a tiled watermark together answer400..epubis no longer accepted.report.docx.pdf, even for a single one.Gotenberg-Output-Filenamestill overrides.Chromium
paperSizenames a format, for LibreOffice too:A3,A4,A5,B4,B5,Letter,LegalorTabloid.waitForWindowStatus, renamed fromwaitWindowStatus, now waits as documented.skipNetworkAlmostIdleEvent=falsenow really waits fornetworkAlmostIdle.400: ascaleout of range, a negative length, awaitDelaylonger than the API timeout. A wait that outlasts the request answers503naming the field and its value.failOnHttpStatusCodesjudges the main page by its frame, not its URL. Screenshotqualitygoes from 1 to 100.--chromium-debug-protocolis set. URL queries and extra header values stay out too.API
archivesunpacks uploaded ZIPs, bounded by--api-archive-max-entriesand--api-archive-max-ratio.NaNand infinities are refused.downloadFromURLs must be absolutehttporhttpsURLs with a host.Gotenberg-Webhook-Events-Urlis required withGotenberg-Webhook-Urland receives errors aswebhook.errorevents: the error URL, method and lists are gone. A failed upload says what the webhook answered, or why it was unreachable.Gotenberg-Output-Filenameis encoded per RFC 6266. Every answer carries the trace header, 404 and 405 included; the version header too, without authentication.--api-bind-iptakes IPv6,--api-start-timeoutbounds module readiness,/debugreports the lok and litho versions.Telemetry
gotenberg.chromium.requests,gotenberg.<engine>.queue.size,chromium.pdf,webhook.send. A failed request carrieserror.type; thestatusattribute and the errors counter are gone.server.addressand aurl.fullstripped of credentials, query and fragment. Outbound URLs lose their query in errors and logs too.4xx, and sets Error on5xxwith the status code aserror.type.OTEL_PROPAGATORSselects the propagators. Each written document is traced, its editing stages as child spans.Security
*_DENY_PRIVATE_IPSchecks, Chromium distrusts the compromised eMudhra roots from the first request, and the pinning proxy stays on with--chromium-host-resolver-rules.500at once.Removed
--log-format,--log-enable-gcp-fields,--api-trace-header,--api-disable-health-check-logging,--chromium-incognito,--webhook-error-allow-listand--webhook-error-deny-listflags, and the--pdfengines-*and--prometheus-*ones.UNOCONVERTER_BIN_PATH, replaced byLOK_BIN_PATH, and the pdfcpu, QPDF, pdftk and ExifTool paths.downloadFrom[].embedded,facturxVersionand the merge bookmark options: the guide names their replacements.Chore
mainand tests the Chromium and LibreOffice variants.v8.40.0: 8.40.0Compare Source
Security Fixes ⚠️
userPasswordandownerPasswordas positional arguments, and it reads an argument that starts with@as a file of further arguments. A password of@/proc/self/cmdline, with newlines in the other one, injected options such as--add-attachment, and the returned PDF embedded any file thegotenberguser can read. QPDF now receives--user-password=and--owner-password=, and every password encrypts the PDF as typed.*_DENY_PRIVATE_IPSchecks let through ranges that IANA marks as not globally reachable, such as the IPv6 benchmarking range2001:2::/48, while they refused its IPv4 twin198.18.0.0/15. They now refuse every such block:0.0.0.0/8, where Docker Desktop answers its host gateway,192.0.0.0/24, the documentation ranges,192.88.99.0/24and240.0.0.0/4in IPv4, and the whole2001::/23block,3fff::/20,5f00::/16and100:0:0:1::/64in IPv6.emSign ECC Root CA - G3until its component updater fetched a CRLSet, about two minutes after each start, and never without access to Google's update servers. Every Chromium restart opened the window again. A managed policy now distrustsemSign ECC Root CA - G3,emSign Root TLS CA - G3andAAA Certificate Servicesat startup.--chromium-host-resolver-rules. Any host-resolver rule turned the pinning proxy off, and with it the only layer that refuses a WebSocket handshake: with--chromium-deny-private-ipsset, a page, or a Web Worker, could open a WebSocket to a private address, and Gotenberg only logged it. Gotenberg now applies the rules itself, with Chromium'sMAPandEXCLUDEsemantics, in its outbound checks and in the proxy, so the IP-class checks judge the address a rule maps a host to.Behavior Changes
--chromium-host-resolver-rulesstops Gotenberg at startup. Chromium skipped a rule it could not parse, so a typo silently sent requests elsewhere.MAPrule knows works as the URL to print, where it returned403before. Hops carried by the environment proxy keep their original host.--chromium-proxy-serverwith an outbound policy logs a warning at startup. WebSocket handshakes reach that proxy without Gotenberg's checks, so enforce the policy there.*_DENY_PRIVATE_IPSchecks refuse more ranges. See the security fix above. The rule covers whole blocks, so a few anycast services inside192.0.0.0/24and2001::/23are refused too.linux/386image needsseccomp=unconfinedon Docker 29.4 and later. Docker's default seccomp profile now deniessocketcallon i386, to block theAF_ALGsockets of CVE-2026-31431, and Gotenberg opens its sockets through it on that architecture. The container fails to start withlisten tcp :3000: socket: function not implemented. Run it with--security-opt seccomp=unconfined, or with a copy of Docker's default profile that allowssocketcall, and keep the host kernel patched. This comes from Docker and affects earlier releases too.Bug Fixes
pdfaon/forms/libreoffice/convertreturned a PDF that was not PDF/A (#1705). Each document got the formats before the merge, which undid them. The formats now apply once, to the merged file, as on/forms/pdfengines/merge. Thanks @APX403.500(#1707). Only an empty content area returned400. Ascaleoutside 0.1 to 2, a negative margin, a zero paper size and every other print parameter Chromium rejects now return400too. Thanks @SergeevDmitry.optimizeImagesswapped images between the pages of a merged PDF (#1708). Two merged documents may give their images the same name, such asX5. Extracted images are now matched by page and name. Thanks @APX403.optimizeImagesmade charts larger (#1714). Charts and other flat-color images often take more space as JPEG than in their lossless stream. A replacement is now kept only when it makes the file smaller, so the pass never grows a PDF. Thanks @APX403.Chore
156.0.8078.79.26.8.2.python3-distutils-extra, and the 45 unused packages it pulled in, from the images that ship LibreOffice (#1711, #1710). Thanks @yusufgngor.v2.15.0in the Makefile, so local and CI linting match.v8.39.0: 8.39.0Compare Source
Security Fixes ⚠️
joption alias and stop loading ExifTool config files. The metadata check blockedjsonbut not its aliasj. A metadata key could import a JSON file carrying aHardLinkpseudo-tag, plant~/.ExifTool_config, and have the next ExifTool run execute it as Perl. The keysj,addtagsfromfile, andalltagsfromfilenow return400, and Gotenberg always runs ExifTool with-config "".http://andhttps://URLs on the URL routes. The default deny-list only coveredfile://, sodevtools://devtools/bundled/devtools_app.htmlloaded Chromium's privileged DevTools page, andwaitForExpressionran there with access to local files./forms/chromium/convert/urland/forms/chromium/screenshot/urlnow return400for any other scheme.wss://deny rules to WebSocket handshakes. The pinning proxy matched CONNECT tunnels againsthttps://host:port, so a deny rule anchored on a path, such as^https?://host/, or onwss://refused the plain request but let the handshake through. The proxy now matches tunnels against each scheme's root URL, and a handshake whose full URL is denied fails the conversion with a generic403.emSign ECC Root CA - G3andAAA Certificate Services, whose intermediates have recoverable private keys. The OS bundle now comes fromca-certificates20250419+deb13u1, and the Java trust store used by PDFtk drops both roots. Correction: Chromium 156 still accepted these chains for about two minutes after each start, until its component updater fetched a CRLSet, and never without access to Google's update servers. The next release, 8.40.0, distrusts both roots in Chromium from the first request. Thanks @hrueger.New Features
failOnConsoleMessageTypesfor Chromium (#1667). Fails the conversion with409when the page logs a console message of one of the given types (log,debug,info,warning,error,assert). The response lists the messages. Thanks @jschneider.pdfaform field now acceptsPDF/A-4on every route that supports it, through the LibreOffice PDF engine. Thanks @henningda.Gotenberg-Versionresponse header (#1693). Set on every authenticated route, error responses included, and on webhook deliveries. It is not set on401responses or/health(#1694). Thanks @fragkakis.Behavior Changes
chrome://,devtools://,data:, and any other scheme besideshttpandhttpsnow return400.~/.ExifTool_config. The metadata keysj,addtagsfromfile, andalltagsfromfilenow return400. Prefix them with a group, for exampleXMP:j, to write a tag of that name.XRECHNUNGFactur-X profile embedsxrechnung.xml. See the bug fix below.Bug Fixes
502on uploads behind HTTP/2 proxies (#1112). Behind Cloud Run with anh2cport, the proxy sent large DATA frames, Go answered with a flood of WINDOW_UPDATE frames, and the proxy dropped the connection mid-upload. Gotenberg now advertises the 16 KiB HTTP/2 default frame size (#1700). Thanks @TessilimiTheo and @geoherna.--api-tls-cert-fileand--api-tls-key-filewith absolute paths left Gotenberg running without accepting connections. Both paths work again, and a missing or unreadable file now fails the startup (#1691). Thanks @n-rodriguez.stampSourceorwatermarkSourcereturned400(#1692). Since 8.36.0, a blank source failed the merge, split, Chromium, and LibreOffice routes. An empty source is skipped again. Thanks @APX403.bearerin lower case (#1696). The Authorization scheme is now matched case-insensitively, as RFC 9110 requires. Thanks @MaxFreedomPollard.XRECHNUNGFactur-X profile embeddedfactur-x.xml(#1701). The spec requiresxrechnung.xmlfor this profile, both as the embedded file and infx:DocumentFileName. Other levels keepfactur-x.xml. Thanks @nhh.Chore
156.0.8078.47.v0.16.3and bumped Go to1.27.3, which fix several HIGH CVEs in the Go standard library andgolang.org/xmodules (#1695). Thanks @sergeykad.1.1.0, which supports Lambda SnapStart (#1704). Thanks @michael-follmann.v2.15.0.Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate CLI.
You can view your changes at https://staging.infra-docs.hamburg.ccc.de/pr186/
ad01d577be0dfaa68d96View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.