Running AWS Lambda with Ubuntu As Docker Base Image For Python Application

Running AWS Lambda with Ubuntu As Docker Base Image For Python Application

Introduction

I was exploring AWS lambda for the implementation of one of the use cases. I had a Python application based on Ubuntu as a base docker image. But when I started exploring running a docker container in AWS Lambda, I found out that they are providing Amazon Linux based on CentOs. But my application had developed based on Ubuntu, so I choose the custom image building with Ubuntu option for Lamda. In this article, I will explain how to run AWS Lambda with Ubuntu as a docker base image.

Prerequisites

  1. AWS IAM user account with AdministratorAccess policy. To create this follow the instructions from the following link https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console

  2. AWS CLI installed and configured. For installation of it follow the guide from the link https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html. For configuration use aws configure command and provide the account name and password in the command line. Follow this guide for more information https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles

  3. Docker installed. For installation follow this link https://docs.docker.com/engine/install/

Docker container in Lambda

We can package Lambda function code and its dependencies in a docker container image. Then we can upload the image to a docker registry (Amazon Elastic Container Registry[ECR]). We need to provide an image ECR url while creating Lambda function. AWS Lambda will pull that image, and start running the Lambda function.

AWS provides a set of open-source base images that you can use to create your container image. These base images include a runtime interface client (RIC) to manage the interaction between Lambda and your function code.

You can also use an alternative base image. Lambda provides open-source runtime interface clients that you add to an alternative base image to make it compatible with Lambda. We are going to implement these steps in this article only.

Create files for sample

app.py
This is the main file which includes the lambda handler function. In this function, just print and returned the message Hello from AWS Lambda using Python

import sys
def handler(event, context):
    print('Hello from AWS Lambda using Python')
    return 'Hello from AWS Lambda using Python' + sys.version + '!'

requirements.txt
This requirements.txt file is used for specifying what Python packages are required to run the project. Currently, we are keeping empty.

Dockerfile
Dockerfile will be as follows

FROM ubuntu:20.04

RUN  apt-get update && apt-get install -y python3-pip   

# Install the function's dependencies using file requirements.txt
# from your project folder.

COPY requirements.txt  .
RUN pip3 install -r requirements.txt 
RUN pip3 install awslambdaric


# Copy function code
COPY app.py .

ENTRYPOINT [ "python3", "-m", "awslambdaric" ]

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

Here we have selected Ububtu 20.04 as the base image. Next command we are updating the package index file in the system and installing python3-pip. Next command is copying requirements.txt from the local directory to the working directory and next command to install the python packages listed in this file.

The next command is very important which is installing runtime interface client (RIC) package of Python which is awslambdaric (https://pypi.org/project/awslambdaric/).
It implements the Lambda Runtime API, allowing you to seamlessly extend your preferred base images to be Lambda compatible. The Lambda Runtime Interface Client is a lightweight interface that allows your runtime to receive requests from and send requests to the Lambda service.

Next we are copying all files from exsting directory(. ) to the working directory of the docker container.

Next with ENTRYPOINT we are specifying exceutable which is awslambdaric that should run when a container is started from a Docker image.

At last with CMD command we are executing our handler function. So when the lambda triggered app.handler function will be invoked.

Now our container image ready, its time to deploy on Lamda.

Build the image and push to ECR

Next we have to create a repository in Amazon ECR.

Log in to Docker in the local machine console with the following command. Replace <region> and <account_id> with your AWS account id.

aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com

Build a docker image with the following command. samplerepo is the repository name we created previously

sudo docker build -t <account_id>.dkr.ecr.<region>.amazonaws.com/samplerepo:latest .

Push build image to AWS ECR with the following command

sudo docker push <account>.dkr.ecr.<region>.amazonaws.com/samplerepo:latest

Create Lambda function

Go to the Lambda console and create a lambda function using the uploaded container image.

After creating the function go to its configuration section and look for Function URL. Create a function URL to trigger this function using this URL in Postman.

Results

Hit the function URL using Postman with GET method and check the results in the Monitor >> Logs section of the lambda function console.

Conclusion

We have successfully run Python application in Docker container on AWS Lambda with Ubuntu as a Docker base image.