{"id":7056,"date":"2019-12-12T15:11:06","date_gmt":"2019-12-12T14:11:06","guid":{"rendered":"https:\/\/www.recolize.com\/?p=7056"},"modified":"2019-12-16T12:35:45","modified_gmt":"2019-12-16T11:35:45","slug":"generate-images-aws-lambda","status":"publish","type":"post","link":"https:\/\/www.recolize.com\/en\/blog\/generate-images-aws-lambda\/","title":{"rendered":"Generate Images From HTML With AWS Lambda"},"content":{"rendered":"<section class=\"section  text-normal section-text-no-shadow section-inner-no-shadow section-normal section-opaque\"  >\n    \n    <div class=\"background-overlay grid-overlay-0 \" style=\"background-color: rgba(0,0,0,0);\"><\/div>\n\n    <div class=\"container container-vertical-default\">\n        <div class=\"row vertical-default\">\n            <div class=\"col-md-12     text-default small-screen-default\"  ><div class=\"col-text-1 text-normal  element-top-20 element-bottom-20\" data-os-animation=\"none\" data-os-animation-delay=\"0s\">\n    <p>A common requirement is to generate images from HTML or CSS code e.g. for barcodes or embedding contents into emails. Running this job on a dedicated server environment often results in over-provisioning the ressources that&#8217;s why AWS Lambda is the perfect solution for that task.<\/p>\n<p><a href=\"https:\/\/aws.amazon.com\/lambda\/features\" target=\"_blank\" rel=\"noopener\">AWS Lambda<\/a> is a serverless computing service which means you do not need to take care of provisioning your hardware, updating the software and upgrading CPU ressources because Amazon does all that for you &#8211; without you even noticing that. Therefore it is an awesome use-case for &#8220;on-off&#8221; workloads. In this blog post we will walk through the different steps that are necessary to run the <a href=\"https:\/\/wkhtmltopdf.org\/\" target=\"_blank\" rel=\"noopener\">wkhtmltoimage<\/a> tool on AWS Lambda to generate images from HTML.<!--more--><br \/>\nBy the way, this mechanism is also used in our <a href=\"https:\/\/www.recolize.com\/en\/releases\/4-2-0-new-feature-email-recommendations\/\">email recommendations<\/a>\u00a0feature, which I suggest to take a look at if you have not done so already.<\/p>\n<p>Up until the mid of 2019 AWS Lambda supported Node.JS version 8.x and the Lambda computing engine used the Amazon Linux AMI version 1. At that time you could easily use an existing <a href=\"https:\/\/www.npmjs.com\/package\/wkhtmltoimage\" target=\"_blank\" rel=\"noopener\">Node.JS library<\/a>\u00a0and run the <em>wkhtmltoimage<\/em> tool and e.g. save the resulting image to an AWS S3 bucket. With the end of the support period of Node.JS 8.x and the switch to Node.JS version 10.x Amazon also decided to <a href=\"https:\/\/docs.aws.amazon.com\/lambda\/latest\/dg\/lambda-runtimes.html\" target=\"_blank\" rel=\"noopener\">change the underlying AMI to version 2<\/a>, which unfortunately does not have the required prerequisites installed any more in order to successfully run the <em>wkhtmltoimage<\/em> binary.<\/p>\n<p>To install the required software components you must include the already compiled library files into your Node.JS function ZIP package that is deployed to AWS Lambda. To compile the libraries the easiest way is to launch a new EC2 instance with the appropriate image.<\/p>\n<h2>Build Steps<\/h2>\n<ol>\n<li>Launch a new micro EC2 instance with the Amazon Linux 2 AMI<\/li>\n<li>Execute the command to install the necessary software packages\n<pre>sudo yum install -y yum-utils rpmdevtools libXrender fontconfig urw-fonts libXext freetype libX11 expat libxcb libXau libjpeg-turbo libpng<\/pre>\n<\/li>\n<li>Execute the commands to download the libraries and extract the compiled files\n<pre>cd \/tmp\r\nyumdownloader libXrender.x86_64 fontconfig.x86_64 libXext.x86_64 freetype.x86_64 libX11.x86_64 expat.x86_64 libxcb.x86_64 libXau.x86_64 libjpeg-turbo.x86_64 libpng.x86_64\r\nrpmdev-extract *rpm<\/pre>\n<p>The Lambda environment uses a 64-bit architecture, therefore it is important to extract the libraries in the <em>x86_64<\/em> format.<\/li>\n<li>Execute the commands\n<pre>sudo mkdir -p \/var\/task\r\nsudo chown ec2-user:ec2-user \/var\/task\r\ncd \/var\/task\r\ncp \/tmp\/*\/usr\/lib64\/* \/var\/task<\/pre>\n<\/li>\n<li>Download the compiled libraries in the folder <em>\/var\/task<\/em> from the EC2 instance e.g. with <em>scp<\/em> command utility<\/li>\n<li>The final step is to include the following files into your Node.JS zip package together with the <em>wkhtmltoimage<\/em> binary:\n<pre>libX11.so.6, libXau.so.6, libXext.so.6, libXrender.so.1, libexpat.so.1, libfontconfig.so.1, libfreetype.so.6, libjpeg.so.62, libpng15.so.15, libxcb.so.1<\/pre>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Now you only need to implement your <em>index.js<\/em> file to generate images from HTML. You can find an example on the <a href=\"https:\/\/www.npmjs.com\/package\/wkhtmltoimage\" target=\"_blank\" rel=\"noopener\">wkhtmltoimage Node.JS wrapper library page<\/a>.<\/p>\n<\/div>\n<\/div>        <\/div>\n    <\/div>\n<\/section>\n\n","protected":false},"excerpt":{"rendered":"<p>A common requirement is to generate images from HTML or CSS code e.g. for barcodes or embedding contents into emails. Running this job on a dedicated server environment often results in over-provisioning the ressources that&#8217;s why AWS Lambda is the perfect solution for that task. AWS Lambda is a serverless computing service which means you<\/p>\n","protected":false},"author":3,"featured_media":7076,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[40],"tags":[],"_links":{"self":[{"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/posts\/7056"}],"collection":[{"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/comments?post=7056"}],"version-history":[{"count":12,"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/posts\/7056\/revisions"}],"predecessor-version":[{"id":7078,"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/posts\/7056\/revisions\/7078"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/media\/7076"}],"wp:attachment":[{"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/media?parent=7056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/categories?post=7056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.recolize.com\/en\/wp-json\/wp\/v2\/tags?post=7056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}