Browser Screenshot Microservice for AWS Lambda
Life can be hard sometimes, especially for a developer. Our journeys from A to B often take us via C, D and Z. This clip from Malcolm in the Middle illustrates this quite well.
<div class="embed-responsive embed-responsive-4by3"> <iframe class="embed-responsive-item" src="https://www.youtube-nocookie.com/embed/AbSehcT19u0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
To get the point of this post – the other day I needed to to make a microservice for taking screenshots of web pages. Just a simple endpoint that would accept a URL and return a screenshot of it.
AWS Lambdas are perfect for this: no servers to run, and just pay per invocation (i.e. per screenshot).
There seemed to be tons of example code to do this, but none of it worked quite right, or there were other problems to deal with:
- Lambda deployment package size must be < 50MB, so you might have to upload Chromium to S3 and pull from there at runtime – another moving part to manage
- Bugs in the latest versions of packages
- The example code had screenshots upload to random services or saved to S3
In short, it got overly complicated.
So my pain is your gain, and having solved these problems I share the solution with you.
lambda-browser-screenshots
The code is available on GitHub. It’s a single-file NodeJS script that builds to a zip that’s only about 42MB, including dependencies. You can easily upload this as a Lambda package without having to pull binaries out of S3.
Building
Build instructions are included in the readme, but essentially, after cloning the repository:
- Run
npm installinside thesrcdirectory. - Zip the
srcdirectory, which should now containnode_modules. - There's no Step 3.
These steps can also be run just by using make.
AWS Setup
Now that you have it built, you can set up your Lambda and upload the zip. I’ll assume you have some prior Lambda knowledge, but the basic setup is:
- Create a new Node.js 12.x Lambda Function
- Add a lambda trigger of type API Gateway
- Set API type to REST API. Configure security and so on.
- Under additional settings, make sure to add image/png to Binary media types, otherwise your screenshots come back as base64 text
Now you can upload the zip file you built previously as the Lambda’s Function code. Although it suggests For files larger than 10 MB, consider uploading using Amazon S3, you’ll probably be fine through the web interface (I have been).
The time it takes to render and screenshot the page (and therefore the overall execution time) depends on how much RAM is allocated to the Lambda function. About 1600MB seems to be a good amount to get the screenshot back within 2-3 seconds. Thus depending on your AWS region you should be able to get 1,000,000 screenshots for around $60 USD.
Usage
Simply make a request to your Lambda URL, and pass the URL you want to screenshot as the url query parameter. You can also optionally specify parameters width and/or height of the browser window. By default these are 1280 and 800, respectively.
Your request must specify the header Accept: image/png. Without it you will receive the image data base 64 encoded, instead of in binary format.
Here’s how to screenshot this very post, using curl:
$ curl -H "Accept: image/png" \
https://functionname.execute-api.region.amazonaws.com/default/browser-screenshots\
\?url\=https://terashift.co.nz/browser-screenshot-microservice-aws-lambda/\
\&width\=1460\&height\=820 \
> browser-screenshot-inception.png
And here is the resulting screenshot.
Conclusion
I hope that you someone finds this tool useful, as a serverless screenshot microservice. Once built and uploaded it should continue to just work without requiring any maintenance.
If you decide you need more features or find that you can upgrade the dependencies to newer versions, while staying under than 50MB limit, please contribute back with a pull request so that rest of the community can benefit as well.
About Tera Shift
Tera Shift Ltd is a software and data consultancy. We help companies with solutions for development, data services, analytics, project management, and more. Our services include:
- Working with companies to build best-practice teams
- System design and implementation
- Data management, sourcing, ETL and storage
- Bespoke development
- Process automation
We can also advise on how custom solutions can help your business grow, by using your data in ways you hadn’t thought possible.
About the author
Ben Shaw (B. Eng) is the Director of Tera Shift Ltd. He has over 15 years’ experience in Software Engineering, across a range of industries. He has consulted for companies ranging in size from startups to major enterprises, including some of New Zealand’s largest household names.
Email ben@terashift.co.nz