Search code examples
pythonamazon-web-servicesaws-lambdadockerfile

How to debug AWS python lambda image locally


I am trying to develop custom runtime in python to stream response, for which i was following this blog as a reference.

dockerfile:

FROM public.ecr.aws/lambda/provided:al2-x86_64

# Install SSL Li
WORKDIR /tmp
RUN yum install -y perl-core zlib-devel gzip wget tar make gcc
RUN wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz 
RUN ls 
RUN tar -xvf openssl-1.1.1l.tar.gz 
RUN cd openssl-1.1.1l \
    && ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib \
    && make \
    && make install
ENV PATH="/usr/local/ssl/bin:${PATH}"
ENV LD_LIBRARY_PATH="/usr/local/ssl/lib:${LD_LIBRARY_PATH}"

# Update YUM
RUN yum update -y

# Download and extract Python
RUN wget https://www.python.org/ftp/python/3.11.1/Python-3.11.1.tgz
RUN tar xvf Python-3.11.1.tgz

# Configure and compile Python
RUN cd Python-3.11.1 && \
    ./configure --enable-optimizations --with-openssl=/usr/local/ssl && \
    make altinstall

# Verify Python and SSL module
RUN python3.11 --version
RUN python3.11 -m ssl

# Copy custom runtime bootstrap
COPY bootstrap ${LAMBDA_RUNTIME_DIR}
RUN chmod +x ${LAMBDA_RUNTIME_DIR}/bootstrap

# requirements.txt
COPY requirements.txt ${LAMBDA_TASK_ROOT}/requirements.txt
RUN python3.11 -m pip install -r ${LAMBDA_TASK_ROOT}/requirements.txt -t ${LAMBDA_TASK_ROOT}/ 

# Copy function code
COPY lambda_function.py ${LAMBDA_TASK_ROOT}/lambda_function.py

RUN python3.11 -m pip install requests

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "lambda_function.handler" ]

lambda_function.py

#! /usr/bin/env python

import json, boto3

client = boto3.client("bedrock-runtime")

def handler(event, context):
    print("handler triggereed")
    return { 
        "statusCode":200,
        "body":"Hello World"
    }
 

    

I built and invoked the container image using this as a reference:

docker build --platform linux/amd64 -t docker-image:test .

installed runtime interface client

run the image.

docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
    --entrypoint /aws-lambda/aws-lambda-rie \
    docker-image:test \
        /usr/local/bin/python -m awslambdaric lambda_function.handler

invoked the container.

curl "http://localhost:9000/2018-06-01/runtime/invocations/next" -d '{}'

the response:

404, page not found

I am unable to find where exactly this is failing.

I looked into logs, but it doesnt show any error log, only one:

<date time> [INFO] {rapid} exec '/usr/file/local/python' (cwd=/tmp, handler=lambda_function.handler)

the entrypoint is set as aws-lambda-rie in the build command. so I was planning to insert debug statements inside the aws-lambda-rie, when i ran after navigating to directory:

cat /aws-lambda-rie

it showed gibberish characters i realized that it is a binary file so I am unable to debug it and determine why is it failing.

also, the debug statement in the lambda function is not printed when i send the request which indicates that request is failing before the handler is triggered.

please provide some direction for where to look into. thanks!


Solution

  • So I found what was I doing wrong:
    I was installing the runtime interface emulator, but since the image is AWS OS-only base image, the runtime interface emulator is already installed and was not required and for the same reason setting the entrypoint as /aws-lambda/aws-lambda-rie was not required. Also the invokation url was not correct see here

    to build and invoke, following steps worked for me:
    docker build --platform linux/amd64 -t docker-image:test .
    then run the container:
    docker run --platform linux/amd64 -p 9000:8080 docker-image:test

    then invoke the container using correct url (from a separate terminal):
    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'