如何在 AWS Lambda 上安装 GraphicsMagick 或 ImageMagick?
How can I install GraphicsMagick or ImageMagick on AWS Lambda?
我正在使用 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 实例。
我安装了(旧)6.x 版本的 ImageMagick,可从 yum
获得。当我 运行 我的脚本在 EC2 实例上安装时,它重现了我在 Lambda 上的代码 运行s 时看到的故障,确认是这个版本的 IM 导致了故障。
如果我用 sudo yum install GraphicsMagick
安装 GraphicsMagick。这允许我的脚本无错误地执行调整大小。
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 中的脚本 运行s 时,可执行文件似乎已损坏。 gm
在调用 gm(buffer).size(/*...*/)
.
时失败并出现以下错误
could not get the image size: ERR:
{"code":"EPIPE","errno":"EPIPE","syscall":"write"}
如何构建可以使用无服务器部署的 ImageMagick 或 GraphicsMagick 版本?
所有依赖项都可以作为 AWS Lambda 函数的一部分打包和上传
如果您可以将其放入 allowed size limits 并上传 zip 文件,您几乎可以使用任何您想要的 AWS Lambda 包。看看 AWS Lambda Deployment Limits
部分
此外,这里有一个如何打包依赖项的示例(针对 python 代码)
我启动了最新的 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 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
我使用工件并构建我自己的 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。这种事情可能只需要做一次。
如果您想解决图像大小调整问题,您还可以查看 serverless sharp image library which uses Sharp,这是一个用于图像大小调整的高性能 Node.js 库,它比 [= 快大约 3 到 5 倍17=]。您没有提供足够的信息来说明它符合您的用例要求,但我只是想提一下,因为到目前为止,这个库已经为我节省了大量 AWS Lambda 成本。
顺便说一句:我与这个项目无关(但许可证是 MIT/Apache 许可证 2.0 无论如何)。
对于node.js,你可以使用node-lambda,它使用docker图像简化了打包:
node-lambda package -I lambci/lambda:build-nodejs6.10 -A . -x '*.lock *.zip'
-I
参数将启动一个 docker 图像并在您的项目中启动 npm i
,因此它将根据正确的体系结构编译二进制文件 node_modules。
如果您在本地设备上安装 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 环境版本更改节点版本。
正如我所检查的,imageMagick 已经存在于 aws lambda 环境中。所以我们可以使用所有与imageMagick相关的库图形、图像。参考:https://serverless.com/blog/building-a-serverless-screenshot-service-with-lambda/
我为此苦苦挣扎了几天,最后自己完成了这个过程,它确实有效。
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
但是有选项:您的 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 函数
3) 带有 AWS Lambda 层的 NodeJS 运行时环境 (npm),为此:
此外,如果您想使用
const imageThumbnail = require('image-thumbnail');
得到了
Runtime.ImportModuleError: Error: Cannot find module 'image-thumbnail'
您应该遵循选项 3:
灵感来自:
https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e
我正在使用 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 实例。
我安装了(旧)6.x 版本的 ImageMagick,可从 yum
获得。当我 运行 我的脚本在 EC2 实例上安装时,它重现了我在 Lambda 上的代码 运行s 时看到的故障,确认是这个版本的 IM 导致了故障。
如果我用 sudo yum install GraphicsMagick
安装 GraphicsMagick。这允许我的脚本无错误地执行调整大小。
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 中的脚本 运行s 时,可执行文件似乎已损坏。 gm
在调用 gm(buffer).size(/*...*/)
.
could not get the image size: ERR:
{"code":"EPIPE","errno":"EPIPE","syscall":"write"}
如何构建可以使用无服务器部署的 ImageMagick 或 GraphicsMagick 版本?
所有依赖项都可以作为 AWS Lambda 函数的一部分打包和上传
如果您可以将其放入 allowed size limits 并上传 zip 文件,您几乎可以使用任何您想要的 AWS Lambda 包。看看 AWS Lambda Deployment Limits
部分
此外,这里有一个如何打包依赖项的示例(针对 python 代码)
我启动了最新的 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 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
我使用工件并构建我自己的 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。这种事情可能只需要做一次。
如果您想解决图像大小调整问题,您还可以查看 serverless sharp image library which uses Sharp,这是一个用于图像大小调整的高性能 Node.js 库,它比 [= 快大约 3 到 5 倍17=]。您没有提供足够的信息来说明它符合您的用例要求,但我只是想提一下,因为到目前为止,这个库已经为我节省了大量 AWS Lambda 成本。
顺便说一句:我与这个项目无关(但许可证是 MIT/Apache 许可证 2.0 无论如何)。
对于node.js,你可以使用node-lambda,它使用docker图像简化了打包:
node-lambda package -I lambci/lambda:build-nodejs6.10 -A . -x '*.lock *.zip'
-I
参数将启动一个 docker 图像并在您的项目中启动 npm i
,因此它将根据正确的体系结构编译二进制文件 node_modules。
如果您在本地设备上安装 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 环境版本更改节点版本。
正如我所检查的,imageMagick 已经存在于 aws lambda 环境中。所以我们可以使用所有与imageMagick相关的库图形、图像。参考:https://serverless.com/blog/building-a-serverless-screenshot-service-with-lambda/
我为此苦苦挣扎了几天,最后自己完成了这个过程,它确实有效。
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
但是有选项:您的 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 函数
3) 带有 AWS Lambda 层的 NodeJS 运行时环境 (npm),为此:
此外,如果您想使用
const imageThumbnail = require('image-thumbnail');
得到了
Runtime.ImportModuleError: Error: Cannot find module 'image-thumbnail'
您应该遵循选项 3:
灵感来自:
https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e