Last updated on May 18th, 2023 at 12:39 pm

In this tutorial we are going to see how easily and quickly you can execute/run and test your lambda functions by building a docker image and running the container on your local Computer / Desktop / MAC / Linux or Windows server.

I am going to execute the sample AWS Lambda function I have on my MAC. One of the awesome feature introduced by AWS as this option will provide us ability in migrating Lambda functions easily to container images.

Steps will be more or less the same in Windows Desktop. This is a simple beginners guide on configuring AWS lambda function within a Docker container.

Lets split this in to clear steps for the ease of understanding

Note: I am using Python 3.9 as an example for this tutorial

For other programming languages refer AWS guide.

Step 1 : Install and Start Docker

You need to first install docker. If you don’t have docker already installed on your local system then follow the details below,
For MAC users, please use this step to install docker
For Windows users, follow this link

Assuming that you have docker installed and started let us go to the next step.

Step 2: Create python file named app.py with code

For the ease of managing the files and contents, let us create a folder / directory named my-lambda. Switch to this directory and proceed with creating a file named app.py and add your code. This can be the same code that you have on your original lambda function. All the files are created inside this my-lambda directory.

This is a demo and I am using very basic function with a package import

from simple_salesforce import Salesforce,SalesforceLogin
def lambda_handler(event, context):
    return {
    "statusCode": 200,
    "headers": {'Content-Type': 'text/html'},
    "body": "<html><body><title>Test Site</title><b>This is a test</b></body></html>"
    }

As you can see I have a dependency for my code and it uses a package named simple_salesforce

Step 3: Create requirements.txt file and add each dependency package line by line

Let us create a requirements.txt file and add the package name that your code depends on, in my case it is simple_salesforce

$cat requirements.txt
simple_salesforce

Step 4: Create Dockerfile

We are all set now to create a dockerfile. Content of the file is shown below.

FROM public.ecr.aws/lambda/python:3.9

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

COPY requirements.txt  .
RUN  pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"

# Copy function code
COPY app.py ${LAMBDA_TASK_ROOT}

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

Since I am using Python3.9, in the header of the file above I am calling that specific image. Take a look at this documentation to understand more https://docs.aws.amazon.com/lambda/latest/dg/python-image.html

Step 5: Build the docker image and run the container

Lets build the docker image now. I am giving my image name as local-lambda

$ docker build -t local-lambda:latest .
[+] Building 29.6s (9/9) FINISHED
 => [internal] load build definition from Dockerfile                                                              0.0s
 => => transferring dockerfile: 37B                                                                               0.0s
 => [internal] load .dockerignore                                                                                 0.0s
 => => transferring context: 2B                                                                                   0.0s
 => [internal] load metadata for public.ecr.aws/lambda/python:3.9                                                 1.6s
 => [1/4] FROM public.ecr.aws/lambda/python:3.9@sha256:6b647484e0a9e9c332e1fc620845d89974cbff3e9008609dbe4a4785  21.3s
 => => resolve public.ecr.aws/lambda/python:3.9@sha256:6b647484e0a9e9c332e1fc620845d89974cbff3e9008609dbe4a4785f  0.0s
 => => sha256:6b647484e0a9e9c332e1fc620845d89974cbff3e9008609dbe4a4785f8cfc054 772B / 772B                        0.0s
 => => sha256:792fdc65bb1f531a3ccdc15c4587133e62f2b136799f3d83b890ceb0f7cb9afa 3.00kB / 3.00kB                    0.0s
 => => sha256:d09805cbf8c0b1ea54f3d29cce364af507e274a7d649a898f40dff058f9f9523 1.58kB / 1.58kB                    0.0s
 => => sha256:069d51b0476dda9214121ccaffa3f73f342eb29db5933390e41138c9b69268fc 104.79MB / 104.79MB                5.9s
 => => sha256:ee7094de4c489a60dfd7ea2c7bbd586a9c1e42f30bff94abf709807174c1200f 85.88kB / 85.88kB                  0.6s
 => => sha256:200b63deca0b4a4920d0089ebd8fd2dcd36e2a61ad1819c02643c089384cba1a 417B / 417B                        0.4s
 => => sha256:072730bdc14dcc7275f5c0d3308c68c0c4826f70118d9c2214b7010c4b4e4122 2.40MB / 2.40MB                    1.9s
 => => sha256:97466eb1c2ad95bd12266c4f07fb8e0aac48a3f198ef3271dba262a1fdb09a74 60.48MB / 60.48MB                 14.0s
 => => sha256:103930488ac486a8141ddf2ca5b8ceb4382f9f6c776d2cb5a692e378f152f320 12.07MB / 12.07MB                  6.4s
 => => extracting sha256:069d51b0476dda9214121ccaffa3f73f342eb29db5933390e41138c9b69268fc                         7.9s
 => => extracting sha256:ee7094de4c489a60dfd7ea2c7bbd586a9c1e42f30bff94abf709807174c1200f                         0.1s
 => => extracting sha256:200b63deca0b4a4920d0089ebd8fd2dcd36e2a61ad1819c02643c089384cba1a                         0.0s
 => => extracting sha256:072730bdc14dcc7275f5c0d3308c68c0c4826f70118d9c2214b7010c4b4e4122                         0.1s
 => => extracting sha256:97466eb1c2ad95bd12266c4f07fb8e0aac48a3f198ef3271dba262a1fdb09a74                         5.0s
 => => extracting sha256:103930488ac486a8141ddf2ca5b8ceb4382f9f6c776d2cb5a692e378f152f320                         1.3s
 => [internal] load build context                                                                                 0.0s
 => => transferring context: 465B                                                                                 0.0s
 => [2/4] COPY requirements.txt  .                                                                                0.2s
 => [3/4] RUN  pip3 install -r requirements.txt --target "/var/task"                                              5.8s
 => [4/4] COPY app.py /var/task                                                                                   0.0s
 => exporting to image                                                                                            0.5s
 => => exporting layers                                                                                           0.5s
 => => writing image sha256:3995f2de2ed7701afd4fb35dc4ff594367eefc4a85e763eec222f2095d5f7b31                      0.0s
 => => naming to docker.io/library/local-lambda:latest

Run docker images command

Verify the list of images and make sure that the above image named local-lambda got successfully build

Lets run the container

$docker run -p 9001:8080 local-lambda
18 Apr 2023 21:17:40,191 [INFO] (rapid) exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)

Step 6: Use CURL to trigger the function

The last step is to invoke the function using CURL and check the logs in the run command, launch a new terminal while keeping the other terminal(that ran the docker run command) open . You should be able to see the logs live by doing so.

$ curl -XPOST "http://localhost:9001/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
{"statusCode": 200, "headers": {"Content-Type": "text/html"}, "body": "<html><body><title>Test Site</title><b>This is a test</b></body></html>"}

In parallel you should be able to see the logs in the terminal window which you ran the docker run command

$ docker run -p 9001:8080 website-lambda
18 Apr 2023 21:17:40,191 [INFO] (rapid) exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)
18 Apr 2023 21:21:29,619 [INFO] (rapid) extensionsDisabledByLayer(/opt/disable-extensions-jwigqn8j) -> stat /opt/disable-extensions-jwigqn8j: no such file or directory
18 Apr 2023 21:21:29,619 [WARNING] (rapid) Cannot list external agents error=open /opt/extensions: no such file or directory
START RequestId: d84871f9-318d-4c89-b4f2-dbdb92627384 Version: $LATEST
END RequestId: d84871f9-318d-4c89-b4f2-dbdb92627384
REPORT RequestId: d84871f9-318d-4c89-b4f2-dbdb92627384	Init Duration: 0.54 ms	Duration: 215.68 ms	Billed Duration: 216 ms	Memory Size: 3008 MB	Max Memory Used: 3008 MB

As I always say, tried my best here to make things simple. Please let me know if you have any questions.

Leave a Reply

Your email address will not be published. Required fields are marked *