chat+ai of LMS_Backend. Keywords for search: wkhtmltopdf,
wkhtmltoimage, wkhtmltox, Snappy, WKHTML_PDF_BINARY, WKHTML_IMG_BINARY, dompdf.
Status: CODE DONE ✅ (24/10/2026), SERVER CLEAN-UP PENDING ⚠️. Every PDF the backend makes is
rendered by dompdf (
barryvdh/laravel-dompdf), a pure-PHP package that composer install
brings in. Nothing has to be installed on a server for PDFs anymore. The wkhtmltopdf binaries can be
uninstalled from each server once the new backend runs there (see Server clean-up).At a glance
Why
- wkhtmltopdf is a system program, installed by hand outside composer on every server and developer machine. A new server without it answered the admin export with a
500. - The project is archived upstream (since January 2023): no new releases and no security fixes, and it is built on an old Qt WebKit engine.
- Only one PDF used it, the admin dashboard export. Invoices, order PDFs and the instructor dashboard export were already rendered by dompdf, so two PDF engines were kept for one file.
What changed in LMS_Backend
Verified: the full backend suite passes (166 tests), and a 5-page sample export (12 months and 52
weeks) was checked page by page: header with logo, company name and export date side by side, table
headers repeated on each new page, and the footer on every page without covering any row.
The admin dashboard export
The request and the response did not change, so the apps need nothing.- 200:
Content-Type: application/pdfandContent-Disposition: attachment; filename=admin_dashboard_20261024_113000.pdf. The A4 report holds the executive summary, the revenue summary (TND), users by role (super admin excluded), users per year, and the monthly and weekly performance tables. - 500:
{ "message": "…" }. Validation errors come back this way too, because the controller’svalidate()sits inside itstry.
Writing PDF views for dompdf
Keep these in mind for any new or changed PDF view (resources/views/*pdf*.blade.php):
No flexbox or grid: use tables
No flexbox or grid: use tables
dompdf supports CSS 2.1 plus a few CSS 3 properties.
display: flex and display: grid are
ignored, so the children stack. Put side-by-side blocks in a <table> (or display: table /
table-cell). border-radius, :nth-child and @page margins work.Fonts: DejaVu Sans, regular and bold only
Fonts: DejaVu Sans, regular and bold only
DejaVu Sans ships with dompdf and covers the • and — characters. It has a regular and a bold
weight only: font-weight: 600 finds no match and falls back to the default serif font. Use
bold (or 700).Images: remote URLs need isRemoteEnabled
Images: remote URLs need isRemoteEnabled
Company logos are R2 URLs. dompdf only downloads them with
->setOption(['isRemoteEnabled' => true]) (every PDF of the backend sets it). A local image must
sit inside the project folder (dompdf’s chroot).Long tables
Long tables
<thead> rows repeat on each new page, and a table breaks between rows, never inside one.Server clean-up
Order matters. Uninstall wkhtmltopdf from a server only after the new backend runs there: the
old code still calls the binary, and the admin export would fail with a
500. Do it once per server
(DEV, TEST, PROD).1
Deploy the new backend
Over SSH, as the site’s system user:If the server deploys through Plesk’s Git integration, pull there and run PHP Composer → Install.
2
Delete the two WKHTML lines from .env
Remove
WKHTML_PDF_BINARY and WKHTML_IMG_BINARY (over SSH, or Plesk → Files → .env →
Edit in Text Editor). Nothing reads them anymore, so a forgotten line does no harm.3
Rebuild the caches
4
Test the export
Sign in as an admin, open the dashboard and download the PDF report. It opens with the company logo,
the tables, and the footer on every page.
5
Uninstall wkhtmltopdf
Needs root. Follow Uninstall the binaries below.
Uninstall the binaries
First find out how it was installed. The old.env pointed at /usr/local/bin, which is where the
official wkhtmltox package from wkhtmltopdf.org puts it.
- wkhtmltox package (.deb / .rpm)
- apt package wkhtmltopdf
- Copied by hand
sudo apt autoremove --purge then removes the libraries the package pulled in
(X11 libraries, xfonts-*) when nothing else needs them. Read the list before you answer y,
and answer n if it names something you don’t recognise.
Check that it is gone:
Developer machines
Delete the two
WKHTML_* lines from the local .env as well, then run composer install and
php artisan optimize:clear.
Rolling back
Not expected to be needed. If it ever is: revert the backend commit, runcomposer install,
reinstall wkhtmltopdf 0.12.6 in /usr/local/bin, and put the two WKHTML_* lines back in .env.