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.

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).

Serverless Computing
A rack loaded up for serverless computing.

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:

  1. Run npm install inside the src directory.
  2. Zip the src directory, which should now contain node_modules.
  3. 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.

Screenshot of Current Post
A screenshot of this post, taken with the screenshot service.

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