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
から入手できるImageMagickの(古い)6.xバージョンをインストールしました。 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のバージョンを構築するにはどうすればよいですか?
最新の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をローカルにコピーし、zipして展開するパッケージに入れました。私のレイアウトはリンクされたawsリポジトリコードに似ていますが、サーバーレス用に変更されています。
ラムダコード:
// 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 もチェックアウトしたい場合があります。この種のことを一度だけ行う必要があるかもしれません。
画像のサイズ変更に取り組む場合は、 サーバーレスのシャープな画像ライブラリ をご覧ください。これは Sharp を使用し、画像のサイズ変更用の高性能Node.jsライブラリですGM/IMと比較して約3倍-5倍高速です。ユースケースの要件に適合するという十分な情報を提供していませんでしたが、このライブラリはこれまでに多くのAWS Lambdaコストを節約していたため、言及したかっただけです。
ところで:私はこのプロジェクトとは関係ありません(ただし、ライセンスはMIT/Apache License 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をコンパイルします。
すべての依存関係は、AWS Lambda関数の一部としてパックおよびアップロードできます
許可されたサイズ制限 に収まる場合は、AWS Lambdaから必要なパッケージをほとんど使用して、Zipファイルをアップロードできます。 AWS Lambda Deployment Limits
セクションをご覧ください
また、依存関係をパッケージ化する方法の例もあります(for python code) https://stackoverflow.com/a/36093281/35801
チェックしたように、imageMagickはawsラムダ環境にすでに存在します。したがって、すべてのライブラリグラフィックス、imageMagickに関連する画像を使用できます。参照: https://serverless.com/blog/building-a-serverless-screenshot-service-with-lambda/
ローカルデバイスに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
アプリをデプロイする前に。
ラムダ環境のバージョンに基づいてノードのバージョンを変更する必要があります。