Lambda development using Docker and Visual Studio Code
Recently, I discovered how easy it is to use VS Code with Docker, and I’ve started using it when developing AWS Lambda code. Having a local environment that closely mirrors the Lambda runtime in the cloud has eliminated many of the classic ‘it works on my machine’ errors—where code runs fine locally but frustratingly fails when deployed. It’s a pet peeve of mine and really takes the enjoyment out of coding—having to incrementally add print statements to isolate where and why an error is occurring in a Lambda function.
This post walks through how I use VS Code and Docker to develop Lambda functions locally, regardless of the deployment method you choose for your code.
VScode
Installed VSCode and AWS CLi and the VSCode extension Dev Containers'. The
Dev Containers’ extension allows you to use a Docker container as your development environment. You’ll also need to have Docker installed on your machine, along with Docker Deskstop, which provides a graphical interface to interact with Docker resources.
Create a Docker Image
The Docker image needs to match the Lambda runtime environment as closely as possible. Details of the base image can be found on their offical Docker image page, and instructions to [create a Docker image] (https://docs.aws.amazon.com/lambda/latest/dg/python-image.html#python-image-instructions) are available in case we want to execute our Lambda function using Docker.
Dockerfile
# Image used by AWS for lambda python
FROM public.ecr.aws/lambda/python:3.13
# Add tar used by VSCode
RUN dnf install -y tar \
&& dnf clean all
# Copy requirements.txt
COPY requirements.txt ${LAMBDA_TASK_ROOT}
# Install the specified packages
RUN pip install -r requirements.txt
# or copy all code from a directory
COPY src/ ${LAMBDA_TASK_ROOT}
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "lambda_function.handler" ]
Since our project is written in Python, we use the official AWS Python base image as the foundation for our Docker image.
When VS Code creates a development container, it uses the Docker image specified in your project’s Dockerfile as the base, then layers additional functionality allowing VSCode to run. This configuration is defined in the devcontainer.json file which we will add shortly .
In the earlier code, where I added tar and zip, those packages are required by the VS Code Docker build process. Without them, the image for VSCode cannot be created successfully.
This file is auto-generated by clicking the blue corner icon in the bottom-left of VS Code (see image below), then selecting “Open Container Configuration File.” You’ll see a number of options—just make sure you add the configuration to your workspace and that it’s based on your project’s Dockerfile.
The resulting file will be located under the .devcontainer directory at the root of your project and will look something like this:
The last step is to add VSCode’s devcontainer.json
to your project. This setups the final Docker image that VScode with the Docker image specified in your Project as it base.
The devcontainer.json file can be auto-generated by clicking the blue box in the bottom-left corner of VS Code (see image below), then selecting Open Container Configuration File
. You’ll see several options—just make sure to add the configuration to the workspace and base it on your project’s Dockerfile. The resulting file will look like this and will be saved under the .devcontainer directory in the root of your project.
Example project
If a file gets added to my S3 bucket send to my email address.
Deploy it as Docker Image
At this stage, you should be able to open VSCode in the same OS environment and packages already existing on Lambda. Exciting stuff for sure!
You may want to test that everything works at this point with a Hello World application. That is if you are planning using this docker image for your lambda.
lambda_function.py (under the src folder)
import json
def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
To upload this on AWS, go to Amazon Elastic Container Registery and create repository. Here you will be able to select detailed instruction to upload the image to the registry
Code
The code can be found here: github reposititory
a test1 A notice displays information that explains nearby content. Often used to call attention to a particular detail.
When using Kramdown {: .notice}
can be added after a sentence to assign the .notice
to the <p></p>
element.
Changes in Service: We just updated our privacy policy here to better service our customers. We recommend reviewing the changes.
Primary Notice: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet.
Info Notice: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet.
Warning Notice: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet.
Danger Notice: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet.
Success Notice: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet.
Want to wrap several paragraphs or other elements in a notice? Using Liquid to capture the content and then filter it with markdownify
is a good way to go.
{% capture notice-2 %}
#### New Site Features
* You can now have cover images on blog pages
* Drafts will now auto-save while writing
{% endcapture %}
<div class="notice">{{ notice-2 | markdownify }}</div>
New Site Features
- You can now have cover images on blog pages
- Drafts will now auto-save while writing
Or you could skip the capture and stick with straight HTML.
<div class="notice">
<h4>Message</h4>
<p>A basic message.</p>
</div>
Message
A basic message.
```mermaid
flowchart LR;
Start-->|scenario,area| M1[Model I]
M1-->F1{feasible?}
F1-->|no| End
F1-->|yes| M2[Model II]
M2-->M3[Model III]
M3-->Complete
```
-
sdfhksdfkdsjfjkhds ↩