vgalin / html2image

A package acting as a wrapper around the headless mode of existing web browsers to generate images from URLs and from HTML+CSS strings or files.
MIT License
354 stars 43 forks source link

Screenshot is not created on linux server #70

Closed Rahimz closed 1 year ago

Rahimz commented 2 years ago

I have an Ubuntu for development and the module works as well with this code;

def png_invoice(request, order_token):
    order = Order.objects.get(token=order_token)
    from html2image import Html2Image
    hti = Html2Image(
        custom_flags=['--no-sandbox'])

    url = request.build_absolute_uri().replace('image/', '')  # it makes my target url 
    filename = f'{order.id}.png'

    hti.output_path = ''.join((settings.MEDIA_ROOT , 'invoice/image/'))
    hti.chrome_path = '/usr/bin/google-chrome/'

    hti.screenshot(url=url, save_as=filename)

    image = open(f"media/invoice/image/{filename}", 'rb')
    response = FileResponse(image)
    return response

This code works correctly on my local machine with ubuntu os but it does not work on my ubuntu server in production. When I try to open the image in the last three lines on my server, it says there is no such file. It means html2image has no errors but it does not save the image on server.

I also check the permission on my server to have read and write permission.

vgalin commented 2 years ago

With no ways to reproduce the issue myself, resolving this issue might be tricky.

Could you add the following line before using screenshot ?

hti.browser.print_command = True

When re-running your program, it will display the commands used to call chrome/chromium. You could then check their syntax, try to run these commands yourself, look for error messages, change the path used, etc.

Rahimz commented 2 years ago

I add this line in my local computer and I have a log like this:

[0625/235209.512941:WARNING:sandbox_linux.cc(376)] InitializeSandbox() called with multiple threads in process gpu-process.
[25/Jun/2022 23:52:09] "GET /static/css/invoice_png_a5.css HTTP/1.1" 200 1307
[25/Jun/2022 23:52:09] "GET /static/debug_toolbar/css/toolbar.css HTTP/1.1" 200 11815
[25/Jun/2022 23:52:09] "GET /static/img/logo_bw.png HTTP/1.1" 200 8125
[25/Jun/2022 23:52:09] "GET /static/css/bootstrap-grid.rtl.css HTTP/1.1" 200 70759
[25/Jun/2022 23:52:09] "GET /static/css/bootstrap.rtl.min.css HTTP/1.1" 200 155949
[25/Jun/2022 23:52:09] "GET /static/css/bootstrap-utilities.rtl.min.css HTTP/1.1" 200 51142
[25/Jun/2022 23:52:09] "GET /static/debug_toolbar/css/print.css HTTP/1.1" 200 43
[25/Jun/2022 23:52:09] "GET /static/debug_toolbar/js/toolbar.js HTTP/1.1" 200 12222
[25/Jun/2022 23:52:09] "GET /static/debug_toolbar/js/utils.js HTTP/1.1" 200 4479
[25/Jun/2022 23:52:09] "GET /static/fonts/IRANSansWebFaNum.woff2 HTTP/1.1" 200 29284
[0625/235209.811407:INFO:headless_shell.cc(660)] Written to file /home/bookstore/media/invoice/image/3574-guest.png.
[25/Jun/2022 23:52:09] "GET /tools/pdf/6c96ba76-fb39-49d9-9b88-3deb94a9aa25/print/image/ HTTP/1.1" 200 112290

It says the file is written and it creates the screenshot in local computer but it could not creates the file on server

vgalin commented 2 years ago

Could you please also provide the exact error message you are getting on your server?

Rahimz commented 2 years ago

There is no error at all. I check the code on server line by line and it seems every line runs correctly. There is no error in Django or Gunicorn. Even this line does not throw any error:

    hti.screenshot(url=url, save_as=filename)

But when I check the destination folder, the file does not save. I check all the permission for the destination folder and my Gunicorn has all the permissions to read, write and execute.

mfumagalli68 commented 2 years ago

Exact same problem here.

Rahimz commented 2 years ago

Today I spent a lot of time to find the error, when I try cli it said you need --no-sanbox flag for Linux, but I could not find any way to define flag in cli. At the end it said the file was created in the folder but there is not any file.

Then I try to make a screenshot in Django shell:

$ python manage.py shell

# my project model
>>> from orders.models import Order
>>> order = Order.objects.filter(active=True, status='approved').first()

# my html source is in this address
>>> url = 'https://example.com/tools/image'

# I set the file name
>>> filename = f'{order.id}-{str(order.client)}.png'

>>> hti = Html2Image(custom_flags=['--no-sandbox'])

# I set the output address based on my project settings
>>> from django.conf import settings
>>> hti.output_path = ''.join((settings.MEDIA_ROOT , 'invoice/image/'))

>>> hti.chrome_path = '/usr/bin/chromium-browser/'

>>> hti.screenshot(url=url, save_as=filename)                                                       

[0717/135207.732450:WARNING:bluez_dbus_manager.cc(247)] Floss manager not present, cannot set Floss enable/disable.
[0717/135257.530982:INFO:child_thread_impl.cc(903)] ChildThreadImpl::EnsureConnected()
[0717/135325.187259:ERROR:network_service_instance_impl.cc(474)] Network service crashed, restarting service.
[0717/135436.065869:WARNING:sandbox_linux.cc(376)] InitializeSandbox() called with multiple threads in process gpu-process.
[0717/135644.589583:INFO:child_thread_impl.cc(903)] ChildThreadImpl::EnsureConnected()
[0717/135653.280813:ERROR:network_service_instance_impl.cc(474)] Network service crashed, restarting service.

After two times that it restarted my network service, and used all server's CPUs, I interrupted with ctrl + c.

I think maybe this error log help you to find the problem. @vgalin

thanks

vgalin commented 2 years ago

I am still not able to reproduce this issue so cannot really offer a solution, as I cannot test things out myself. As the GPU is mentionned in the error messages, you could try to add the --disable-gpu flag before taking a screenshot, but it usually doesn't change anything.

This is clearly a Chromium-related issue and I think you'll have more luck by searching on this side, on the official official chromium bugtracker for example, or other discussion threads.

When searching for chromium headless "Network service crashed, restarting service." for example, I can find threads like this, but again I cannot try the offered solutions myself: https://bbs.archlinux.org/viewtopic.php?id=268123

You may also want to try out different Chromium versions and see if it changes anything.