如何在AWS Lambda上安装GraphicsMagick或ImageMagick?

时间:2017-06-23 19:58:06

标签: node.js imagemagick aws-lambda graphicsmagick serverless-framework

我正在使用Node.js的gm包以及AWS Lambda上提供的默认ImageMagick安装。

const gm = require('gm').subClass({ imageMagick: true });

由于某些原因,某些图像的调整大小功能失败。

我使用Amazon Linux AMI(ami-hvm-2016.03.3.x86_64-gp2)创建了一个EC2实例。 我安装了yum提供的(旧)6.x版ImageMagick。当我在EC2实例上使用该安装运行我的脚本时,它会重现我在Lambda上运行代码时看到的失败,确认此版本的IM导致失败。

如果我使用sudo yum install GraphicsMagick安装GrpahicsMagick。这允许我的脚本无错误地执行调整。

const gm = require('gm').subClass({ imageMagick: false });

但是,我不确定如何在我的无服务器部署中捆绑这个。如果我将GraphicsMagick安装到与sudo yum --installroot=/var/task install GraphicsMagick的脚本相同的文件夹中,并使用此require语句运行我的脚本:

const gm = require('gm').subClass({ imageMagick: false, appPath: './usr/bin/' });

我在EC2实例上运行脚本时调整大小。但是,当我使用无服务器进行部署,并且脚本在Lambda中运行时,可执行文件似乎已损坏。调用gm时,gm(buffer).size(/*...*/)失败并显示以下错误。

could not get the image size: ERR: {"code":"EPIPE","errno":"EPIPE","syscall":"write"}

如何构建可以无服务器部署的ImageMagick或GraphicsMagick版本?

8 个答案:

答案 0 :(得分:18)

我旋转了最新的aws linux并运行了下面的命令。

yum -y install gcc-c++ libpng-devel libjpeg-devel libtiff-devel wget
wget https://downloads.sourceforge.net/project/graphicsmagick/graphicsmagick/1.3.26/GraphicsMagick-1.3.26.tar.gz
tar zxvf GraphicsMagick-1.3.26.tar.gz
cd GraphicsMagick-1.3.26
./configure --prefix=/var/task/graphicsmagick --enable-shared=no --enable-static=yes
make
sudo make install
tar zcvf ~/graphicsmagick.tgz /var/task/graphicsmagick/

我将dir打到我的本地,然后将它扔进包装中进行拉链和展开。我的布局类似于链接的aws repo代码,但是针对无服务器进行了修改。

Lambda代码:

// graphicsmagick dir is at the root of my project
const BIN_PATH = process.env['LAMBDA_TASK_ROOT'] + "/graphicsmagick/bin/";
const Gm = require('gm').subClass({ appPath: BIN_PATH });

// below is inside the handler
process.env['PATH'] = process.env['PATH'] + ':' + BIN_PATH;

serverless.yml

package:
  artifact: /path/to/function.zip

我使用神器并构建自己的拉链。如果你遇到下面的问题,我建议你这样做。 https://github.com/serverless/serverless/issues/3215

# -y to keep the symlinks and thus reduce the size from 266M to 73M
cd lambda && zip -FS -q -r -y ../dist/function.zip *

抓住了想法:

https://gist.github.com/bensie/56f51bc33d4a55e2fc9a

https://github.com/awslabs/serverless-image-resizing

编辑: 可能还要查看lambda layers。可能只需要做一次这样的事情。

答案 1 :(得分:6)

如果你想解决图像大小调整问题,你也可以看看使用serverless sharp image library Sharp的{{3}},这是一个高性能的Node.js库,用于图像大小调整,比你快3倍 - 5倍转到GM / IM。您没有提供足够的信息来说它符合您的用例要求,但我只是想提一下,因为这个库到目前为止已经为我节省了大量的AWS Lambda成本。

顺便说一句:我与这个项目无关(但许可证仍然是麻省理工学院/ Apache许可证2.0)。

答案 2 :(得分:3)

我在这方面苦苦挣扎了几天,最终自己完成了该过程,并且确实有效。

ImageMagick不再与Node.js 10.x运行时捆绑在一起。有3个选项可以使ImageMagick与Node.js 10.x函数一起使用:

1)打包依赖项,并将其包含在您上载的ZIP文件中(像这样)

https://image-magick-example.s3-us-west-2.amazonaws.com/image-magick-example.zip

https://github.com/hmagdy/imagemagick-aws-lambda-Node.js10.x/tree/master/option1_image-magick-example-zip

但具有以下选项: Lambda函数“ image-magick-example-zip-demo”的部署包太大,无法启用内联代码编辑。但是,您仍然可以调用函数。

enter image description here

2)创建或使用包含ImageMagick的Lambda图层来做到这一点:

clone git@github.com:hmagdy/imagemagick-aws-lambda-Node.js10.x.git
cd imagemagick-aws-lambda-2
start Docker services
make all

这将在构建文件夹中创建一个 layer.zip 。但是,为了节省您一些时间,您可以使用一个zip文件来创建Lambda图层。

https://image-magick-layer.s3-us-west-2.amazonaws.com/layer.zip

创建图层时,请确保添加Node.js 10.x作为受支持的运行时。然后,您可以将函数设置为使用最新的Node.js 10.x,并添加创建的图层。图像转换将再次起作用!

enter image description here

然后您可以像这样创建aws lambda函数

https://github.com/hmagdy/imagemagick-aws-lambda-Node.js10.x/tree/master/option2_image-magick-example-c_lib_layer/index.js

3)具有AWS Lambda层的NodeJS运行时环境(npm),可以做到这一点:

此外,如果您想使用

const imageThumbnail = require('image-thumbnail');

得到

Runtime.ImportModuleError: Error: Cannot find module 'image-thumbnail'

您应遵循选项3:

https://github.com/hmagdy/imagemagick-aws-lambda-Node.js10.x/tree/master/option3_image-magick-example-npm_layer

灵感来自:

https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e

答案 3 :(得分:1)

可以将所有依赖项打包并作为AWS Lambda函数的一部分上载

如果您可以将其放在allowed size limits中并上传zip文件,那么您几乎可以使用任何您想要的AWS Lambda软件包。请查看AWS Lambda Deployment Limits部分

此外,这是一个如何打包依赖项的示例(对于python代码)https://stackoverflow.com/a/36093281/358013

答案 4 :(得分:1)

对于node.js,您可以使用node-lambda,它使用泊坞窗图像简化了打包:

node-lambda package -I lambci/lambda:build-nodejs6.10 -A . -x '*.lock *.zip'

-I参数将启动一个docker镜像并在项目中启动npm i,以便它针对正确的架构编译二进制node_modules。

答案 5 :(得分:0)

如果在本地设备上安装Docker并将此命令添加到package.json中。

"dockerbuild": "rm -rf node_modules/gm && docker run -v \"$PWD\":/var/task lambci/lambda:build-nodejs8.10 npm install"

在部署应用之前运行npm run dockerbuild

您应根据lambda环境的版本更改节点版本。

答案 6 :(得分:0)

就我而言,我无法从/ var / task获得执行GraphicsMagick的权限。 我复制到/ tmp并给予它755的权限,如上所述:AWS Lambda making video thumbnails 您是否愿意分享您是如何克服这个问题的?

答案 7 :(得分:0)

当我检查时,imageMagick已经存在于AWS Lambda环境中。因此,我们可以使用所有库图形,即与imageMagick相关的图像。请参阅:https://serverless.com/blog/building-a-serverless-screenshot-service-with-lambda/