Introduction
In this post, we’ll turn a simple AWS Lambda function into a running Docker container so you can test your functions locally on your own machine. This greatly improves efficiency testing and speeds up your development process.
The setup
Debugging Lambdas is not easy. How can we run functions locally for easier testing?
Let’s say you have a folder that contains just two files for an AWS function:
$ ls -lash
0 drwxr-xr-x 26 srvrlss srvrlss 832B Aug 25 11:53 .
8 -rw-r--r-- 1 srvrlss srvrlss 500K Aug 24 12:02 index.js
8 -rw-r--r-- 1 srvrlss srvrlss 156B Aug 24 13:54 package.json
Contents of index.js:
exports.handler = async (event, context) => {
let body = JSON.stringify({hello: "world"});
let statusCode = 200;
console.log("body stringified" + body);
return {
statusCode,
body,
// headers
};
};
Adding a Dockerfile
First, add a Docker file with Amazon’s basic Node.js Lambda image, as you see on line 1:
FROM amazon/aws-lambda-nodejs:14
COPY package.json ${LAMBDA_TASK_ROOT}
RUN npm install
COPY index.js ${LAMBDA_TASK_ROOT}
CMD ["index.handler"]
- On line 3, we copy
package.jsoninto the container. - On line 4, we run the command to install any packages required for your function.
- On line 6, we add your
index.jsfile. - Finally, on line 8, we define what our function
"handler"is.
Note: ${LAMBDA_TASK_ROOT} is a variable that’s defined in the base Amazon image, so you don’t need to define it.
AWS automatically detects which of their supported languages you’re using based on the image specified on line 1 of the Docker file.
Building and Running the container
Now that we have a Docker file we can build this image with:
docker build . -t mylambda:latest
And execute it by running:
docker run -t mylambda:latest
If everything went well, you should see something in the likes of:
INFO[0000] exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)
You now have you lambda running! Perfect, let’s restart, but now we’ll connect Lambdas’ default port to our host so we can interact with it.
docker run -p 8080:8080 -t mylambda:latest
Intuitively, you’re inclined to open your browser and go directly to the page. However, that’s not how Amazon’s Lambdas work. They’re routed internally, so we can’t directly access them. Instead, we have to use a tool like Postman for example to execute a post request to a specific URL (someone from Amazon, please explain to me why this works like this):
/2015-03-31/functions/function/invocations
We need that URL to send the json contents we want the function to execute.
Interacting with your function
So we just learned that functions are a little hidden. No stress, we can still reach the function.
Here’s a simple curl call that will just invoke the function without anything else:
curl -XPOST "http://localhost:8080/2015-03-31/functions/function/invocations" -d '{}'
Response
If your container is running correctly, your function shell should now show a few extra lines with Amazon information, plus any other logging you might have added.
INFO[0003] extensionsDisabledByLayer(/opt/disable-extensions-jwigqn8j) -> stat /opt/disable-extensions-jwigqn8j: no such file or directory
WARN[0003] Cannot list external agents error="open /opt/extensions: no such file or directory"
START RequestId: 2e60c804-664b-4edf-9050-aa7fca84bb8b Version: $LATEST
2021-09-05T13:12:31.465Z 2e60c804-664b-4edf-9050-aa7fca84bb8b INFO body stringified{"hello":"world"}
END RequestId: 2e60c804-664b-4edf-9050-aa7fca84bb8b
REPORT RequestId: 2e60c804-664b-4edf-9050-aa7fca84bb8b Init Duration: 0.41 ms Duration: 113.84 ms Billed Duration: 114 ms Memory Size: 3008 MB Max Memory Used: 3008 MB
That’s it!
Note: I added a console.log in the index.js file, which is the reason you will see the body stringified text in the response. It should contain the result of your executed code. Results may vary depending on your index.js contents.
Sadly, the solution feels rather hacky, and if you know of a better way to do this, we’re all ears. Share your thoughts with us!
We have also written a tutorial to run a Cloudflare Worker Locally
If you like this kind of content and would like more detailed or complex scenarios, help us by sharing this article or reaching out via the contact form!

Thijs is an entrepreneur and software developer who started building websites at age 9.
With over 15 years in tech and a decade in content delivery, he focuses on product development, architecture, and security.
He believes technology should feel intuitive, not complicated, and builds scalable, human-centered solutions that make a real impact.
Outside of work, he enjoys reading everything from business strategy to science fiction.


