node.js - ¿Cómo puedo instalar GraphicsMagick o ImageMagick en AWS Lambda?
aws-lambda serverless-framework (5)
Hice girar el último aws linux y ejecuté los comandos a continuación.
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 el directorio en mi local y lo lancé en el paquete para ser comprimido y desplegado. Mi diseño es similar al código de repositorio aws vinculado, pero modificado para sin servidor.
Código 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
Uso el artefacto y construyo mi propio zip. Si se encuentra con el siguiente problema, le sugiero que lo haga. 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 *
Ideas tomadas de:
https://gist.github.com/bensie/56f51bc33d4a55e2fc9a
https://github.com/awslabs/serverless-image-resizing
Editar: es posible que también desee ver las capas lambda . Puede que solo necesite hacer este tipo de cosas una vez.
Estoy usando el paquete
gm
para Node.js junto con la instalación predeterminada de ImageMagick que está disponible en AWS Lambda.
const gm = require(''gm'').subClass({ imageMagick: true });
Por alguna razón, la funcionalidad de cambio de tamaño falla para ciertas imágenes.
Creé una instancia EC2 con Amazon Linux AMI (ami-hvm-2016.03.3.x86_64-gp2).
Instalé la versión (antigua) 6.x de ImageMagick que está disponible en
yum
.
Cuando ejecuto mi script con esa instalación en la instancia EC2, reproduce la falla que veo cuando el código se ejecuta en Lambda, confirmando que es algo con esta versión de IM que está causando la falla.
Si instalo GrpahicsMagick con
sudo yum install GraphicsMagick
.
Esto permite que mi script realice los cambios de tamaño sin error.
const gm = require(''gm'').subClass({ imageMagick: false });
Sin embargo, no estoy seguro de cómo agrupar esto en mi implementación con serverless.
Si instalo GraphicsMagick en la misma carpeta que el script con
sudo yum --installroot=/var/task install GraphicsMagick
y ejecute mi script usando esta declaración require en su lugar:
const gm = require(''gm'').subClass({ imageMagick: false, appPath: ''./usr/bin/'' });
El cambio de tamaño funciona cuando ejecuto mi script en la instancia EC2.
Pero cuando despliego con serverless, y el script se ejecuta en Lambda, el ejecutable parece estar roto.
gm
falla con el siguiente error en una llamada a
gm(buffer).size(/*...*/)
.
could not get the image size: ERR: {"code":"EPIPE","errno":"EPIPE","syscall":"write"}
¿Cómo puedo construir una versión de ImageMagick o GraphicsMagick que pueda implementarse sin servidor?
Para node.js, puede usar node-lambda , simplifica el empaquetado usando una imagen acoplable:
node-lambda package -I lambci/lambda:build-nodejs6.10 -A . -x ''*.lock *.zip''
El argumento
-I
lanzará una imagen acoplable y lanzará
npm i
en su proyecto para que compile los módulos_nodo binarios contra la arquitectura correcta.
Si desea abordar el cambio de tamaño de la imagen, también puede echar un vistazo a la biblioteca de imágenes nítidas sin servidor que utiliza Sharp , una biblioteca Node.js de alto rendimiento para el cambio de tamaño de la imagen que es aproximadamente 3x - 5x más rápido en comparación con GM / IM. No proporcionó suficiente información para decir que se ajusta a los requisitos de su caso de uso, pero solo quería mencionarlo ya que esta biblioteca ya me ahorró muchos costos de AWS Lambda hasta ahora.
Por cierto: no estoy relacionado con este proyecto (pero las licencias son MIT / Apache License 2.0 de todos modos).
Si instala Docker en su dispositivo local y agrega este comando a su package.json.
"dockerbuild": "rm -rf node_modules/gm && docker run -v /"$PWD/":/var/task lambci/lambda:build-nodejs8.10 npm install"
Ejecute
npm run dockerbuild
antes de implementar su aplicación.
Debe cambiar la versión del nodo según la versión de su entorno lambda.
Todas las dependencias se pueden empaquetar y cargar como parte de su función AWS Lambda
En su mayoría, puede usar cualquier paquete que desee de AWS Lambda, si puede ajustarlo dentro de los
límites de tamaño permitidos
y cargar el archivo zip.
Eche un vistazo a la sección
AWS Lambda Deployment Limits
Además, aquí hay un ejemplo de cómo empaquetar dependencias (para código python) https://.com/a/36093281/358013