Dynamic HTML with Python, AWS Lambda, and Containers

Deploying AWS Lambda using a container


FROM public.ecr.aws/lambda/python:3.8
RUN mkdir -p /mnt/app
ADD app.py /mnt/app
ADD index.html /mnt/app
WORKDIR /mnt/app
RUN pip install --upgrade pip
RUN pip install Jinja2==2.11.*
CMD ["/mnt/app/app.handler"]

App code

From the Dockerfile, we can see that all application code is contained in two files:

import os
from jinja2 import Environment, FileSystemLoader
def handler(event, context):
env = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), "."), encoding="utf8"))
my_name_from_query = False
if event["queryStringParameters"] and "my_name" in event["queryStringParameters"]:
my_name_from_query = event["queryStringParameters"]["my_name"]
template = env.get_template("index.html")
html = template.render(
return {
"statusCode": 200,
"body": html,
"headers": {
"Content-Type": "text/html",

Calling and testing the app locally

Testing the app locally is very simple thanks to the new container packaging. Simply run

docker-compose -f docker-compose.yml up
version: '3'
container_name: cont_name
image: cont_name_img
context: .
dockerfile: Dockerfile
- .:/mnt/app
- "9000:8080"
stdin_open: true
tty: true
restart: always
import requests
r = requests.get(
data=open("event.json", "rb")
"queryStringParameters": {
"my_name": "Adam"


The simple AWS base server returns responses such as the one below. This is where we can see the significant impact of the new 1ms pricing update. The cost of running this example code is about 9ms which is very small considering that we are returning a full html template to browsers. However, previously AWS would charge for the full 100ms because that is the minimum charge allowed. Now, this function could cost nearly 90% less!

Lambda duration



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store