DEV Community

Deploying a Django project on AWS Lambda using Serverless (Part 1)

Vadym Khodak on April 16, 2021

BLUF As a follow-up to a post where we looked at the most common questions about Django in the Cloud, now, I'd like to help you deploy y...
Collapse
 
changchingchung profile image
John

If my understanding is correct, Lambda's main use is to map one API endpoint to one Lambda function.

In your example, you put the whole Django APP in it and map any http request to it, which means no matter what API you call, it will only and always invoke this Lambda Django APP to respond.

Does this lose the point of one API, one Lambda function?

Collapse
 
vaddimart profile image
Vadym Khodak

Yes, you understand this correctly.
Here is one Lambda - wsgi server which is Django App.
As I mentioned in my posts this is probably not the best solution for production app with many connections which require a quick response.
But it can for many other scenarios like MVP, app without many connections and great performance.
If you wanted to make your API as a one Lambda function I would recommend you to look at AWS Chalice library.
I'm sorry for such short answer.
I am not able to make it deeper and better because I'm on the front line of Ukrainian - russian war.

Collapse
 
kostjapalovic profile image
Kostja Appliku.com

Great article. Grew my curiosity about serverless framework.

Okay, Question here.

How it compares with Zappa? Have you tried it? I’ve built one big project with it (in terms of amount of code, no production usage so far).

Thoughts about Zappa:

  • Easy to deploy
  • Easy to get SSLed custom domain
  • convenient json configuration
  • Had to suffer a bit to make WeasyPrint (for generating PDFs) work, had to create an additional Layer with required files.
  • loved their @task decorator to make async functions
  • scheduling of function execution in json files works pretty cool too.

With non-production amount of traffic it is kind of slow at times. For example, when I work alone and test the app and there is an async task (I click something that causes email sending in @task function - it feels like it doesn’t go async. Or it take a while for another instance to spin up (watching cloudwatch logs in terminal).

Launch of that app is soon, so I am thrilled to see how all this stuff will behave.

But with initial learning curve, before I see any benefits of scaling, I think that could be better off with small ec2 instance.

Collapse
 
vaddimart profile image
Vadym Khodak

Hi Kostja,

I didn't have experience with Zappa. I tried it one time.
Zappa/Serverless is just a one of ways to deploy Django App on AWS infrastructure.
I think for some cases it will be better to use Zappa for other casses it is better to use Serverless or something else.

The same thing is about using EC2 instances vs AWS Lambdas.

About using nice json format, from my personal point of view yaml is more human readble format than json. But it is just my personal opinion. ("Many people many minds")

I have a couple of small projects (based on trafic) where Django is deployed on AWS Lambdas and it works well.

Regarding async task, I may be wrong, I think that if it will not work as async function if you call it from sync function. Django is not async framework, as far as I know.

Thank you for your comment here. I appreciate it.

Collapse
 
kostjapalovic profile image
Kostja Appliku.com

Hey. Thanks for the response.

I don't honestly care about json vs yaml. I mean i will not go in a holywar abou it :D but probably yaml is more human readable.

Anyway, the whole question was to make sure if i am missing out on not looking hard into the Serverless framework, maybe it is somehow superior to Zappa or anything like that.

From what I understand it is not and both are just possible options, if I understood you right. Thanks again.

Now about async stuff.

If a function is wrapped in a Zappa @task, then when it is called it checks if it is called in lambda environment. in this case it invokes a lambda function goes on.

So this invocation on cold dev/staging environment(when there are no concurrent requests, for example when only one me playing with the app) it takes quite a while to invoke it. But it feels that it gets faster once at least 2-3 people work with the app in parallel.

Anyway. Thanks again for the post!
Great work!

Thread Thread
 
vaddimart profile image
Vadym Khodak

Thank you for the feedback.

In Serverless you also can call another Lambda function from Django Lambda. But I think it is a bit more complex than just @task decorator. There are a lot of plugins for Serverless framework. One of them serverless-plugin-warmup. It can help you to keep warm your lambdas.

Collapse
 
a5s_s7r profile image
A5S S7R

Hi Vadim,

I found this very interesting tutorial, as I am looking for an easy way to host a Django app with low traffic.

Just got curious about your approach of setting up the docker container.
Maybe I missed some context, as I am pre first coffee.
Is there a reason you did't create a Dockerfile with FROM amazonlinux:latest?

Thanks for the great tutorial!

Collapse
 
vaddimart profile image
Vadym Khodak

Hi Andreas,
Thank you for the comment.
Creating a docker container is not a required step, but I had issues deploying serverless apps to AWS Lambdas from MacOS.
It is better to deploy serverless app from the same OS as AWS Lambda runtime.
Based on AWS documentation, it is Amazon Linux 2 for Python 3.8.

Let me know if you have any additional questions

Collapse
 
alexbellin profile image
alexbellin

I'm not well versed on docker, but I found most of the other sections very thorough.

  • How do we get the requirements.txt and package.json files onto the docker container?
  • what about the source code files?

Otherwise, many thanks for this great tutorial

Collapse
 
vaddimart profile image
Vadym Khodak

Thank you for the comment.
Unfortunately, I'm not able to help you right now since I had to join the Ukraine Army to defend my country.
I'll answer all questions after our victory!
Slava Ukraine!

Collapse
 
alexbellin profile image
alexbellin

After a bit on research, I found that I needed to be at the root directory when running the docker run command. The -v command seems to copy the src to /root/src (seperated by colon)

Collapse
 
sumankanukollu profile image
sumankanukollu

I enjoyed reading this article.

Small correction is required in "production.py" file like mentioned in below lines: (Because our StaticRootS3Boto3Storage and MediaRootS3Boto3Storage classes placed in storages.py file

STATICFILES_STORAGE = "django_aws_lambda.utils.storages.StaticRootS3Boto3Storage"
DEFAULT_FILE_STORAGE = "django_aws_lambda.utils.storages.MediaRootS3Boto3Storage"
Enter fullscreen mode Exit fullscreen mode
Collapse
 
pedrozan profile image
Pedro Henrique Schleder

The django app will live inside the lambda? Will it have to spin up on every equest?

Collapse
 
vaddimart profile image
Vadym Khodak

Great question! Thank you for asking!
I wasn't able to find a right answer.
But here is a link to some article about related topic
acloudguru.com/blog/engineering/ho...!

As I mentioned in the beginning of the post it is not the best solution for applications with many requests and with necessity to respond really fast.

Also, there is a serverless plugin that can help to warmup your lambda (serverless-plugin-warmup).

Collapse
 
pedrozan profile image
Pedro Henrique Schleder

Thanks for answering, I will look into it. Forgot to say I really liked the idea and the tutorial 😁

Thread Thread
 
vaddimart profile image
Vadym Khodak

My pleasure, happy to help

Collapse
 
andoromain profile image
Andoromain • Edited

Hi Vadym, i have an error when i want to execute my lambda function
{
"errorMessage": "Unable to import django-aws-lambda.wsgi.application",
"errorType": "Exception",
"stackTrace": [
" File \"/var/lang/lib/python3.8/imp.py\", line 234, in load_module\n return load_source(name, filename, file)\n",
" File \"/var/lang/lib/python3.8/imp.py\", line 171, in load_source\n module = _load(spec)\n",
" File \"\", line 702, in _load\n",
" File \"\", line 671, in _load_unlocked\n",
" File \"\", line 843, in exec_module\n",
" File \"\", line 219, in _call_with_frames_removed\n",
" File \"/var/task/wsgi_handler.py\", line 115, in \n wsgi_app = import_app(config)\n",
" File \"/var/task/wsgi_handler.py\", line 48, in import_app\n raise Exception(\"Unable to import {}\".format(config[\"app\"]))\n"
]
}

Could you help me?

Collapse
 
vaddimart profile image
Vadym Khodak

Unfortunately, I don't have enough time right now since I'm in Ukraine Army fighting against the russians.
I can advice you just try to start from scratch. Everything should work.
Sorry that I'm not really helpful.

Collapse
 
kenny1323 profile image
kenny1323 • Edited

Next time you can create everything inside the container.
pull image001
docker run container001 from image001
docker exec -it container001 bash

now you are inside the bash shell of the container001

apt install python django python-env git
mkdir project001
git clone http//project001.git
etc..

Collapse
 
radek profile image
RadekTester

Great article. I really liked it!