spatie / laravel-pdf

Create PDF files in Laravel apps
https://spatie.be/docs/laravel-pdf
MIT License
728 stars 56 forks source link

[Bug]: How to use laravel-pdf with Ubuntu 24.04 and the new "AppArmor" #194

Open thewruck opened 2 weeks ago

thewruck commented 2 weeks ago

What happened?

I am new to laravel and laravel-pdf. Working on saving my first PDF, but got hit with this error. But this seems to be a security feature into Ubuntu 24.04 and not a bug. I am seeing many ways to just turn AppArmor off, but I am looking for instructions on how to correctly give permissions for the AppArmor to stay on, but allowances made for laravel-pdf to run. Seems like the documentation needs to be updated as I am sure to be the first of many who get hit with this "feature"

How to reproduce the bug

Running this code...

        return Pdf::view('reports.attendance_sheets', ['course_instances' => $course_instances])
        ->format('letter')
        ->name('attendance-sheets.pdf');

...generates this error

Symfony \Component \Process \Exception\ ProcessFailedException
PHP 8.2.23
11.31.0
The command "PATH=$PATH:/usr/local/bin:/opt/homebrew/bin NODE_PATH=`npm root -g` node '/home/user/dev/project/vendor/spatie/browsershot/src/../bin/browser.cjs' 
'{"url":"file:\/\/\/tmp\/2134164357-0644410001731471148\/index.html","action":"pdf","options":{"args":[],"viewport":
{"width":800,"height":600},"displayHeaderFooter":false,"format":"letter","printBackground":true}}'" failed. Exit Code: 1(General error) Working directory: /home/user/dev/project/public
Output: ================ Error Output: ================ sh: 1: npm: not found 
Error: Failed to launch the browser process! [12473:12473:1112/221228.961379:FATAL:zygote_host_impl_linux.cc(128)] No usable sandbox! If you are running on Ubuntu 23.10+ or another Linux distro that has disabled unprivileged user namespaces with AppArmor, see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md. 
Otherwise see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md 
for more information on developing with the (older) SUID sandbox. 
If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox. TROUBLESHOOTING: https://pptr.dev/troubleshooting at ChildProcess.onClose 
(/home/user/dev/project/node_modules/@puppeteer/browsers/lib/cjs/launch.js:314:24) at ChildProcess.emit (node:events:529:35) at ChildProcess._handle.onexit (node:internal/child_process:292:12)

Package Version

1.5.2

PHP Version

8.2.23

Laravel Version

11.31

Which operating systems does with happen with?

Linux

Notes

No response

irsyadadl commented 1 week ago

Same issue here.

thewruck commented 1 week ago

I stumbled on a 'fix', but i still do not know what is the proper way to deal with this.

Down in the <project_path>/vendor/spatie/browsershot/src is Browsershot.php. It contains a bunch of properties. I just set $noSandbox to true. I am sure that there is a better way to pass this in, but I did not see it in any of the documentation.

class Browsershot
{
    ...

    protected string $html = '';

    protected bool $noSandbox = true;

    protected string $proxyServer = '';

    ...
irsyadadl commented 1 week ago

What the hell, did you modify the vendor?

kharchenko-san commented 1 week ago

@thewruck Here is the documentation that describes how to customize the Browsershot instance: https://spatie.be/docs/laravel-pdf/v1/advanced-usage/customizing-browsershot

In your case, to disable the sandbox:

return Pdf::view('reports.attendance_sheets', ['course_instances' => $course_instances])
    ->format('letter')
    ->withBrowsershot(function (Browsershot $browsershot) {
        $browsershot->noSandbox();
    })
    ->name('attendance-sheets.pdf');