Подтвердить что ты не робот

Как установить GraphicsMagick или ImageMagick на AWS Lambda?

Я использую пакет gm для Node.js вместе со стандартной установкой ImageMagick, доступной на AWS Lambda.

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

По некоторым причинам, функция изменения размера не работает для определенных изображений.

Я создал экземпляр EC2 с Amazon Linux AMI (ami-hvm-2016.03.3.x86_64-gp2). Я установил (старую) версию 6.x ImageMagick, доступную с yum. Когда я запускаю свой сценарий с этой установкой на экземпляре EC2, он воспроизводит ошибку, которую я вижу, когда код запускается на Lambda, подтверждая, что это что-то с этой версией IM, которая вызывает ошибку.

Если я установлю GraphicsMagick с sudo yum install 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. Но когда я выполняю развертывание с помощью serverless, и скрипт запускается в Lambda, исполняемый файл оказывается поврежденным. gm завершается ошибкой со следующей ошибкой при вызове gm(buffer).size(/*...*/).

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

Как я могу создать версию ImageMagick или GraphicsMagick, которая может быть развернута без сервера?

4b9b3361

Ответ 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/

Я отправляю каталог в свой локальный каталог и бросаю его в пакет, который нужно сжать и развернуть. Мой макет похож на код репозитория 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

Я использую артефакт и строю свой собственный почтовый индекс. Если вы столкнетесь с проблемой ниже, я предлагаю вам сделать это. 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

Редактировать: Возможно, вы захотите также проверить лямбда-слои. Может быть, нужно сделать это только один раз.

Ответ 2

Если вы хотите заняться изменением размера изображения, вы также можете взглянуть на безсерверную библиотеку резких изображений, которая использует Sharp, высокопроизводительную библиотеку Node.js для изменения размера изображения, которая примерно в 3 раза - в 5 раз быстрее по сравнению с GM/IM. Вы не предоставили достаточно информации, чтобы сказать, что она соответствует вашим требованиям варианта использования, но я просто хотел упомянуть об этом, поскольку эта библиотека уже сэкономила мне много затрат на AWS Lambda.

Кстати: я не связан с этим проектом (но лицензии MIT/Apache License 2.0 в любом случае).

Ответ 3

Все зависимости могут быть упакованы и загружены как часть вашей функции AWS лямбда

Вы можете использовать любой пакет из AWS Lambda, если вы можете поместить его в допустимые ограничения размера и загрузить zip файл, Взгляните на раздел AWS Lambda Deployment Limits

Кроме того, здесь приведен пример того, как упаковывать зависимости (для кода python) fooobar.com/questions/419722/...

Ответ 4

Для node.js вы можете использовать node-lambda, это упрощает упаковку с использованием изображения докеров:

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

Аргумент -I запустит образ докера и запустит npm i в вашем проекте, чтобы он скомпилировал двоичный файл node_modules по правильной архитектуре.

Ответ 5

Если вы устанавливаете 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 перед развертыванием приложения.

Вам следует изменить версию узла в зависимости от версии вашей лямбда-среды.