|
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