Cómo Utilizar Docker con AWS Lambda para Entornos Ubuntu APT

 

Si utilizas AWS Lambda y, por alguna razón, necesitas un entorno personalizado mediante Docker, este artículo es para ti. Aquí te explicaré en qué consiste el proceso y los desafíos que enfrenté al implementarlo, para que puedas ahorrar tiempo y evitar posibles obstáculos.


Contexto

Al implementar funciones en AWS Lambda, Amazon proporciona imágenes base en Amazon Elastic Container Registry (ECR) que puedes utilizar. Sin embargo, en mi caso, necesitaba un entorno que no utilizara Yum (el gestor de paquetes de Amazon Linux), sino Apt (el gestor de paquetes de Ubuntu). Esto se debe a que algunas librerías y paquetes que requería para mi aplicación estaban disponibles o eran más fáciles de manejar en Ubuntu.

Para lograr esto, utilicé una imagen base de Node.js en Ubuntu y la especificación de plataforma AMD64:

FROM --platform=linux/amd64 node:lts

Sin embargo, un aspecto que parece simple pero que me tomó más tiempo de lo esperado fue instalar el AWS Lambda Runtime Interface Client (RIC) globalmente:

npm install -g aws-lambda-ric

El aws-lambda-ric es un emulador del entorno de ejecución de Lambda que permite que tu contenedor personalizado sea compatible con Lambda.

Para ahorrarte tiempo, aquí te dejo el código completo del Dockerfile que utilicé, junto con algunas explicaciones adicionales.


Dockerfile Completo




Explicación Detallada

Explicación Detallada

  • Imagen Base: Utilizamos node:lts para tener la versión LTS de Node.js sobre un sistema Ubuntu.

FROM --platform=linux/amd64 node:lts
  • Variables de Entorno: Definimos rutas y variables que serán utilizadas posteriormente.

ARG LAMBDA_TASK_ROOT="/app" ARG LAMBDA_RUNTIME_DIR="/usr/local/bin" ARG PLATFORM="linux/amd64"
  • Instalación de Dependencias: Actualizamos apt-get e instalamos todas las librerías y herramientas necesarias. Aquí puedes agregar o eliminar paquetes según tus necesidades.

RUN apt-get update && \ apt-get install -y \ ghostscript \ dvisvgm \ g++ \ make \ cmake \ unzip \ libcurl4-openssl-dev \ autoconf \ automake \ build-essential \ libtool \ m4 \ python3 \ libssl-dev && \ rm -rf /var/lib/apt/lists/*
  • Instalación del AWS Lambda RIC: Instalamos el aws-lambda-ric de forma global para que el contenedor pueda comunicarse correctamente con el entorno de Lambda.

RUN npm install -g aws-lambda-ric
  • Copia del Código y Dependencias: Copiamos el código de la función Lambda al contenedor y ejecutamos npm install para instalar las dependencias de Node.js.

COPY ./ ${LAMBDA_TASK_ROOT}/ RUN npm install
  • Configuración de NPM: Creamos un directorio temporal para evitar advertencias de NPM relacionadas con permisos y rutas.

dockerfile
  • Copy code

    RUN mkdir -p /tmp/.npm/_logs ENV npm_config_cache=/tmp/.npm

  • Runtime Interface Emulator (Opcional): Añadimos el Runtime Interface Emulator para facilitar las pruebas locales.

ADD "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie" "/usr/bin/aws-lambda-rie" COPY entry.sh / RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
  • Punto de Entrada y Comando por Defecto: Establecemos el script de entrada y el handler de la función Lambda.

ENTRYPOINT ["/entry.sh"] CMD ["dist/infrastructure/server.handler"]

Archivo entry.sh

Es posible que necesites un script de entrada (entry.sh) para iniciar la aplicación correctamente. Aquí tienes un ejemplo:


#!/bin/sh 
# Comprueba si el script se está ejecutando en un entorno de Lambda o localmente 
if [ -z "$AWS_LAMBDA_RUNTIME_API" ]; then 
  # Si no está en Lambda, utiliza el Runtime Interface Emulator 
  exec /usr/bin/aws-lambda-rie /usr/local/bin/npx aws-lambda-ric $@ 
else 
  # Si está en Lambda, ejecuta normalmente 
  exec /usr/local/bin/npx aws-lambda-ric $@ 
fi

Asegúrate de dar permisos de ejecución al script:

chmod +x entry.sh

Notas Adicionales

  • Personalización: Puedes agregar o quitar paquetes en la sección de instalación de dependencias según las necesidades de tu aplicación.

  • Compatibilidad: Al especificar --platform=linux/amd64, te aseguras de que la imagen sea compatible con AWS Lambda, ya que actualmente no soporta ARM en contenedores personalizados.

  • Optimización: Recuerda limpiar la caché de apt-get y otros archivos temporales para reducir el tamaño de la imagen.

Conclusión

Utilizar contenedores Docker personalizados con AWS Lambda te permite tener mayor control sobre el entorno de ejecución de tus funciones. Sin embargo, es importante configurar correctamente el entorno para asegurar la compatibilidad y el correcto funcionamiento.

Al compartir mi experiencia y el código que utilicé, espero ahorrarte tiempo y facilitarte el proceso. Si estás en una situación similar, te recomiendo considerar esta opción para aprovechar las ventajas de AWS Lambda con un entorno personalizado que satisfaga tus requerimientos.

Recursos Adicionales


Espero que este artículo te haya sido útil y que puedas implementar tus funciones Lambda con Docker de manera más eficiente. ¡No dudes en compartir tus experiencias o preguntas en los comentarios!

Comentarios