Installing Node Canvas in AWS Lambda

Using node-canvas on AWS Lambda can be a pain because node-canvas has dependencies. A simple yarn add or npm install will not suffice.

node-canvas

Automattic's node-canvas extends the familiar canvas API in the browser to Node. With node-canvas you can draw shapes, apply text and overlay images. The data types node-canvas interfaces with are interchangeable. For example, you can apply text and images to a canvas and stream the canvas PDF, png, jpg, array buffer, and so forth.

The Problem

AWS Lambda is runs on Amazon's special flavor of linux.

Node-canvas requires a few packages like Cairo and Pango to function. To get Node-canvas up and running on AWS lambda, you need to compile native libraries in an identical EC2 instance. Next, copy the binaries from the server to your local machine and include them in your package that you upload to AWS lambda.

The Solution

The quick and dirty solution is to git clone this repo: https://github.com/unshift/canvas-lambda.git

The lib directory includes the .so files and a latest, precompiled version of canvas (v1.6.7 - the latest as of this writing).

The trick to getting AWS lambda to recognize the path to the native modules is to modify the environmental variables PATH, LD_LIBRARY_PATH, PKG_CONFIG_PATH.

process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/lib';
process.env['LD_LIBRARY_PATH'] = process.env['LAMBDA_TASK_ROOT'] + '/lib';
process.env['PKG_CONFIG_PATH'] = process.env['LAMBDA_TASK_ROOT'] + '/lib';

Next, drop the binaries in the lib directory of the root of your lambda function, e.g.:

  • handler.js
  • node_modules
  • lib
  • package.json

Pre-Compiling node-canvas on EC2

Use this bash script to install dependencies: https://gist.github.com/unshift/cdebd9a1da98816514789b62cbe7797d

install_node_canvas_binaries.sh installs the following at /canvas/:

  • libpng
  • jpegsrc
  • pixman
  • freetype
  • cairo
  • giflib
  • libxml2
  • fontconfig

Next it copies the native modules to /var/task/lib.

/var/task is where Lambda functions live.

The last step is to npm install canvas (discussed below).

EC2 Setup

  • Spin up an EC2 instance using the latest Amazon Machine Image (http://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html)
  • SSH into the box.
  • You can switch to root by issuing the command sudo su -.
  • Install node: sudo yum install nodejs npm --enablerepo=epel

Run the script

cd /tmp
wget https://gist.githubusercontent.com/unshift/cdebd9a1da98816514789b62cbe7797d/raw/57a11195bb6ab9aae13dc4f97eec8ce2b0b5a771/install_node_canvas_binaries.sh
sh install_node_canvas_binaries.sh
cd /var/task/lib
npm install canvas
cd node_modules/canvas
node-gyp rebuild

Further Reading