如何在 AWS Lambda 上安装 GraphicsMagick 或 ImageMagick?
Posted
技术标签:
【中文标题】如何在 AWS Lambda 上安装 GraphicsMagick 或 ImageMagick?【英文标题】:How can I install GraphicsMagick or ImageMagick on AWS Lambda? 【发布时间】:2017-11-27 11:39:17 【问题描述】:我正在使用适用于 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
安装 GraphicsMagick。这允许我的脚本执行调整大小而不会出错。
const gm = require('gm').subClass( imageMagick: false );
但是,我不确定如何在我的部署中将其与无服务器捆绑在一起。如果我使用 sudo yum --installroot=/var/task install GraphicsMagick
将 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 版本?
【问题讨论】:
【参考方案1】:我启动了最新的 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/
我将目录 scp 到我的本地并将其放入要压缩和部署的包中。我的布局类似于链接的 aws 存储库代码,但针对无服务器进行了修改。
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
我使用工件并构建自己的 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。这种事情可能只需要做一次。
【讨论】:
更改为 ./configure --prefix=/var/task/graphicsmagick --enable-shared=no --enable-static=yes 我正在为依赖库苦苦挣扎...例如,当我在 lambda 上运行 gm 时找不到 libjpeg.so.62 除了列出的软件包之外,我还必须安装tar
、gzip
和 make
。代替 scp 的另一个选项是(在主机上)运行 docker cp [container id]:/root/graphicsmagick.tgz ./
你在哪里运行这些命令。我创建了一个 lambda 函数,它给了我同样的错误并且在本地运行良好。您能否指定运行命令的方式和位置?
我的简单 lambda 函数的 serverless.yml 在哪里?【参考方案2】:
我为此苦苦挣扎了几天,最终自己经历了这个过程,它确实有效。
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”的部署包太大,无法启用内联代码编辑。但是,您仍然可以调用您的函数。
或
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 并添加您创建的层。然后图像转换应该会再次工作!
然后您可以像这样创建您的 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
【讨论】:
我刚刚上传了图层(第 2 步),它立即开始工作。非常感谢!伟大的工作【参考方案3】:如果您想解决图像大小调整问题,您还可以查看serverless sharp image library,它使用了Sharp,这是一个用于图像大小调整的高性能 Node.js 库,与 GM/IM 相比,速度大约快 3 到 5 倍.您没有提供足够的信息来说明它符合您的用例要求,但我只想提一下,因为到目前为止,这个库已经为我节省了很多 AWS Lambda 成本。
顺便说一句:我与这个项目无关(但许可证无论如何都是 MIT/Apache 许可证 2.0)。
【讨论】:
在切换之前记住夏普的限制:sharp.pixelplumbing.com/en/stable/api-input/#limitinputpixels 如果你想处理大图像,那可能是个问题。 夏普也有同样的问题。你需要有 docker 来构建它。【参考方案4】:所有依赖项都可以作为 AWS Lambda 函数的一部分打包和上传
如果您可以将其放入 allowed size limits 并上传 zip 文件,您可以主要使用 AWS Lambda 提供的任何包。看看AWS Lambda Deployment Limits
部分
另外,这里有一个如何打包依赖的例子(对于python代码)https://***.com/a/36093281/358013
【讨论】:
我已经在包中安装了 imagemagick,我可以在 node_modules 文件夹中看到它。但它仍然给出了同样的错误。在本地,我已经在 ubuntu 上安装了 imageMagick,它运行良好。不知道怎么在lambda环境下安装。 @OsamaKhalid 您没有安装在 lambda 环境中。在这种情况下,您将打包所有依赖项,即 imageMagick。参考这个例如***.com/questions/36054976/pandas-aws-lambda/…【参考方案5】:对于node.js,你可以使用node-lambda,它使用docker镜像简化了打包:
node-lambda package -I lambci/lambda:build-nodejs6.10 -A . -x '*.lock *.zip'
-I
参数将启动一个 docker 映像并在您的项目中启动 npm i
,以便它会针对正确的架构编译二进制 node_modules。
【讨论】:
你如何部署无服务器?serverless deploy
?【参考方案6】:
如果您在本地设备上安装 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 环境的版本更改节点版本。
【讨论】:
【参考方案7】:我检查过,imageMagick 已经存在于 aws lambda 环境中。所以我们可以使用所有与imageMagick相关的库图形、图像。参考:https://serverless.com/blog/building-a-serverless-screenshot-service-with-lambda/
【讨论】:
以上是关于如何在 AWS Lambda 上安装 GraphicsMagick 或 ImageMagick?的主要内容,如果未能解决你的问题,请参考以下文章
你如何在Typescript中优雅地导入AWS-Lambda?
如何使用 AWS Lambda 在 AWS EMR 上运行 PySpark