Laravel snappy on Laradock error /usr/local/bin/wkhtmltopdf not found

1.1k Views Asked by At

Context

I have deployed a Laravel app using Laradock. This app has the feature to generate certificates in PDF and attach them to an email notification.

Everything works fine in Laravel Homestead (development environment), however, that feature is not working in Laradock production mode.

Goal

I have implemented a functionality to send a PDF certificate through an email notification as an attachment like so (using Laravel Filament):

<?php

use Illuminate\Support\Facades\Notification;
use App\Notifications\Certificates\CertificateIssued;


Notification::route('mail',[
  $certificate->participant->email=>$certificate->participant->name,               
])->notify(new CertificateIssued($record));

Now in the notification class CertificateIssued I instantiate a Laravel Snappy PDF generator class

    public function toMail($notifiable)
    {
        $generateCertificate = new GenerateCertificate();
        //...
        return
            (new MailMessage)->markdown('emails.certificates.issued',[
            //Some vars to be passed
            ])
        ->attachData($GenerateCertificate->attachPDF($this->certificate),$pdf_filename, [
                'mime' => 'application/pdf',
            ]);
    }

The Laravel Snappy PDF certificate class is like so:


use App\Models\Certificate;
use App\Services\Certificates\Qr\GenerateQr;
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;

class GenerateCertificate
{
    public function attachPdf(Certificate $certificate)
    {
        $pdf = $this->generate_pdf_certificate($certificate);

        return $pdf->output();
    }

    public function generate_pdf_certificate(Certificate $certificate)
    {
        //QR code
        $qr=$this->generate_png_qr($certificate);

        //load blade view
        $pdf = PDF::loadView('certificates.default',compact('certificate','qr'));

        //Set PDF options. todo: abstract options away
        $pdf = $this->setPdfOptions($pdf);

        return $pdf;
    }

    public function genera_qr_png(Certificate $certificate)
    {
        $generateQR = new GenerateQr($this->generate_url_qr_verification($certificate),'png',130);
        return $generateQR->image();
    }
}

So I want the PDF attachment to be sent on an email notification. That piece of code is also used in a scheduler for newly generated certificates to be sent via email.

Error

But the email sending notification cannot be achieved due to an error in the wkhtmltopdf

[2022-05-19 16:40:53] production.ERROR: The exit status code '127' says something went wrong: stderr: "sh: /usr/local/bin/wkhtmltopdf: not found

.env

I have actually installed the WKHTMLTOPDF in both the workspace and php-fpm containers.

###########################################################
################ Containers Customization #################
###########################################################

### WORKSPACE #############################################
WORKSPACE_INSTALL_WKHTMLTOPDF=true


### PHP_FPM ###############################################
PHP_FPM_INSTALL_WKHTMLTOPDF=true


Inside the container,

> docker exec -it --user=laradock project_workspace_1 zsh
➜  www git:(master) ✗ /usr/local/bin/wkhtmltopdf -V
wkhtmltopdf 0.12.6 (with patched qt)
➜  www git:(master) ✗ ls -lah /usr/local/bin
total 92M
drwxr-xr-x 1 root     root     4.0K May 18 10:18 .
drwxr-xr-x 1 root     root     4.0K Apr 16  2021 ..
-rwxr-xr-x 1 laradock www-data 2.6M Apr 22 19:48 composer
-rwxr-xr-x 1 root     root      221 May 18 10:15 pip
-rwxr-xr-x 1 root     root      221 May 18 10:15 pip3
-rwxr-xr-x 1 root     root      221 May 18 10:15 pip3.10
-rwxr-xr-x 1 root     root      221 May 18 10:15 pip3.8
-rwxr-xr-x 1 root     root      238 May 18 10:15 virtualenv
-rwxr-xr-x 1 root     root      208 May 18 10:15 wheel
-rwxr-xr-x 1 laradock www-data  45M Jun 10  2020 wkhtmltoimage
-rwxr-xr-x 1 laradock www-data  45M Jun 10  2020 wkhtmltopdf

I can see it is indeed installed in /usr/local/bin/ and I can actually execute it. Even if the owner is root:root, but I changed it to laradock:www-data but it made no difference.

What works and main question

I have another functionality to generate a certificate preview that works as a PDF download which does work. So why does this PDF preview download works and not the PDF attachment?

Here is a PDF generator preview that generates a PDF and prompts for download in the browser (using Laravel Filament):

    public function certificate_preview(){
        $event = Event::with('relationships...')->findOrFail($this->record->id);
        $pdf = SnappyPdf::loadView('certificates.default',['event'=>$this->record])
            ->setPaper('Letter')
            ->setOrientation('Portrait')
            ->setOption('disable-external-links', false)
            ->setOption('enable-local-file-access', true)
            ->setOption('enable-internal-links' , true)
            ->output()
        ;
        $disk = Storage::disk('pdf');
        $disk->put('preview.pdf', $pdf);

        return Storage::disk('pdf')->download('preview.pdf');//https://dev.to/fractalbit/tips-for-working-with-private-files-in-laravel-1g08

        //dd(Storage::disk('pdf')->path('preview.pdf'));

        //dd($this->record);
    }

The previous code streams the PDF in the browser as a download option or it simply shows it right in the browser:

blob:https://myapp.com/long_uuid_string

where I can see perfectly the PDF! But why isn't the attachment working and outputs the

ERROR: The exit status code '127' says something went wrong: stderr: "sh: /usr/local/bin/wkhtmltopdf: not found" at /var/www/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php:469

error?

Version info

The version of wkhtmltopdf is:

➜  www git:(master) ✗ /usr/local/bin/wkhtmltopdf -V
wkhtmltopdf 0.12.6 (with patched qt)
➜  www git:(master) ✗ php -v
PHP 8.1.5 (cli) (built: Apr 21 2022 10:14:45) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.5, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.5, Copyright (c), by Zend Technologies

Problem identified

I have tested to send an email notification without the queue in jobs and it worked!

Looks like the php-worker container should have the WKHTMLTOPDF installed, which is missing in the .env file.

I mean, there's no

### PHP_WORKER ############################################
PHP_WORKER_INSTALL_WKHTMLTOPDF=true

in the PHP-WORKERsection.

So now the question is, how to install that extension in the php-worker container?

0

There are 0 best solutions below