|
1 | | -# Changes on this repository |
| 1 | +# About node-canvas |
2 | 2 |
|
3 | | -Due to the size of dependencies, i.e. node_modules folder, it is no longer available to edit any serverless app based on this blueprint using AWS Lambda inline editor with node-canvas version 2.0+. So, I update this repository as resource space for those who would like to use node-canvas in their AWS Lambda functions. |
| 3 | +[node-canvas](https://github.com/Automattic/node-canvas) is a Cairo backed Canvas implementation for Node.js by [Automattic](https://github.com/Automattic). It is an implementation of the Web Canvas API and implements that API as closely as possible. For API documentation, please visit [Mozilla Web Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). See [Compatibility Status](https://github.com/Automattic/node-canvas/wiki/Compatibility-Status) for the current API compliance. |
4 | 4 |
|
5 | | -In order to use node-canvas on AWS Lambda, there is an official guide from [Automattic](https://github.com/Automattic). For native dependencies like libcairo.so.2 and others, you may use the files I uploaded to this repostory. |
| 5 | +# About lambda-node-canvas |
6 | 6 |
|
7 | | -# Getting node-canvas works on AWS Lambda |
8 | | - |
9 | | -Node canvas is a Cairo backed Canvas implementation for NodeJS by [Automattic](https://github.com/Automattic). Following is the snapshot of Installation Guide from [official wiki](https://github.com/Automattic/node-canvas) last updated on Sep 3, 2018. |
10 | | - |
11 | | -**Canvas 2.0 and 1.6 works out-of-the-box on AWS Lambda thanks to prebuilds. However, you must build your Lambda ZIP file on Linux (or a Linux Docker container) so that the correct prebuilt binary is included.** See https://github.com/Automattic/node-canvas/issues/1231 for more info. |
12 | | - |
13 | | -The below instructions can be used for older versions or custom builds. |
14 | | - |
15 | | ---- |
16 | | - |
17 | | -Lambda doesn't have the required libraries installed by default, but it can load them from either the `./` or `./lib` directories in your packaged function. |
18 | | - |
19 | | -Create an EC2 VM from the [the Lambda AMI](https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html), we'll use this to build canvas and grab compatible libraries. |
20 | | - |
21 | | -Install Node and development tools: |
22 | | - |
23 | | -```bash |
24 | | -sudo yum groupinstall "Development Tools" -y |
25 | | -curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash |
26 | | - |
27 | | -# Exit SSH session and reopen here to make nvm available |
28 | | - |
29 | | -# Node 6.10: |
30 | | -nvm install 6.10 |
31 | | -# Or Node 8.10: |
32 | | -nvm install 8.10 |
33 | | -``` |
34 | | - |
35 | | -Install node-canvas as you normally would on Linux: |
36 | | - |
37 | | -```bash |
38 | | -sudo yum install cairo-devel libjpeg-turbo-devel giflib-devel pango-devel -y |
39 | | -npm install canvas@next |
40 | | -``` |
41 | | - |
42 | | -Then copy the system libraries from `/usr/lib64/` into a `./lib/` subdirectory for your Lambda function: |
43 | | - |
44 | | -``` |
45 | | -mkdir lib |
46 | | -cp /usr/lib64/{libpng12.so.0,libjpeg.so.62,libpixman-1.so.0,libfreetype.so.6,\ |
47 | | -libcairo.so.2,libpango-1.0.so.0,libpangocairo-1.0.so.0,libpangoft2-1.0.so.0} lib/ |
48 | | -``` |
49 | | - |
50 | | -At this point you can package up the `node_modules` and `lib` directories and download them to your local machine. The `node_modules/canvas/build/Release/canvas.node` library has been built for the Lambda architecture, so don't overwrite it by rebuilding the canvas package on your local machine. |
51 | | - |
52 | | -Then you can add an `index.js` handler to test Canvas with: |
53 | | - |
54 | | -```js |
55 | | -let |
56 | | - {createCanvas} = require("canvas"); |
57 | | - |
58 | | -function hello(event, context, callback) { |
59 | | - let |
60 | | - canvas = createCanvas(200, 200), |
61 | | - ctx = canvas.getContext('2d'); |
62 | | - |
63 | | - // Write "Awesome!" |
64 | | - ctx.font = '30px Impact'; |
65 | | - ctx.rotate(0.1); |
66 | | - ctx.fillText('Awesome!', 50, 100); |
67 | | - |
68 | | - // Draw line under text |
69 | | - let |
70 | | - text = ctx.measureText('Awesome!'); |
71 | | - ctx.strokeStyle = 'rgba(0,0,0,0.5)'; |
72 | | - ctx.beginPath(); |
73 | | - ctx.lineTo(50, 102); |
74 | | - ctx.lineTo(50 + text.width, 102); |
75 | | - ctx.stroke(); |
76 | | - |
77 | | - callback(null, '<img src="' + canvas.toDataURL() + '" />'); |
78 | | -} |
79 | | - |
80 | | -module.exports = {hello}; |
81 | | -``` |
82 | | - |
83 | | -You can now zip up this function and manually deploy it to Lambda (just set Node to 6.10 and the handler to `index.hello`), or you can deploy it using [Serverless](https://serverless.com/). For Serverless, add a `serverless.yml` file to the root of your project: |
84 | | - |
85 | | -``` |
86 | | -service: canvas-test |
87 | | -
|
88 | | -provider: |
89 | | - name: aws |
90 | | - runtime: nodejs6.10 |
91 | | - stage: dev |
92 | | - region: us-east-1 |
93 | | - memorySize: 128 |
94 | | - timeout: 10 |
95 | | -
|
96 | | -functions: |
97 | | - hello: |
98 | | - handler: index.hello |
99 | | -``` |
100 | | - |
101 | | -The resulting project structure: |
102 | | - |
103 | | -``` |
104 | | -├── index.js |
105 | | -├── lib |
106 | | -│ ├── libcairo.so.2 |
107 | | -│ ├── libfreetype.so.6 |
108 | | -│ ├── libjpeg.so.62 |
109 | | -│ ├── libpango-1.0.so.0 |
110 | | -│ ├── libpangocairo-1.0.so.0 |
111 | | -│ ├── libpangoft2-1.0.so.0 |
112 | | -│ ├── libpixman-1.so.0 |
113 | | -│ └── libpng12.so.0 |
114 | | -├── node_modules |
115 | | -│ ├── canvas |
116 | | -│ .... |
117 | | -│ └── nan |
118 | | -│ .... |
119 | | -└── serverless.yml |
120 | | -``` |
121 | | - |
122 | | -Call `serverless deploy` to deploy it to Lambda, and `serverless invoke --function hello` to run it, and you should get back the HTML for this successful result: |
123 | | - |
124 | | - |
125 | | - |
126 | | -## Using newer versions of libcairo |
127 | | - |
128 | | -The version of Amazon Linux that Lambda uses includes libcairo v1.12, which produces noticeably poor results when downscaling images with `drawImage()`. This was fixed in Cairo v1.14. You can use the install instructions for EC2 ([[Installation - Amazon-Linux-AMI-(EC2)]]) to build libcairo 1.14 and libpixman 0.34 from source, and replace the `libcairo.so.2` and `libpixman-1.so.0` binaries in your Lambda's `lib` directory with the resulting libraries (you can find those built libraries in `/usr/local/lib`). |
129 | | - |
130 | | -However, due to the ordering of the directories in Lambda's `LD_LIBRARY_PATH` (`/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib`) the operating system's included libcairo and libpixman will be used instead of the copies in your Lambda's `lib` directory. To fix this you need to set LDFLAGS during canvas installation: |
131 | | - |
132 | | -```bash |
133 | | -export LDFLAGS=-Wl,-rpath=/var/task/lib |
134 | | -npm install canvas@next |
135 | | -``` |
136 | | - |
137 | | -This will set the RPATH flags in the built `canvas.node` library to look for libraries in `/var/task/lib` first (your Lambda's bundled `lib` directory). Update the copy of `canvas.node` in your Lambda's `lib` directory with this newly-built version. |
| 7 | +lambda-node-canvas is an implementation of node-canvas for manipulating vector graphics on AWS Lambda, with using AWS Lambda Layer to manage the dependency with node-canvas in order to enable inline editing of the function code. |
0 commit comments