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


    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