Exploring Options for Deploying Django Web App
Tags: deployment, aws, django, heroku
Published: 2021-01-10 14:17:36



In this article, I have written about different deployment options for Django DRF a.k.a Django Rest Framework based web applications.

To keep things simple across all platforms and have an estimated monthly hosting cost, we will assume that our app currently only uses Postgres as a database. Our hosting options would allow having other external dependencies like ElasticSearch, Redis, Worker Queues but we won’t include them in our comparison for simplicity in pricing and configuration.

##**Heroku:**

Starting with the easiest and quickest to configure, **_this is my go-to recommendation for anyone just starting out_** and they don’t have any scalability requirements or preference. It comes with an easy to configure Git integration and Pipelines setup as well. You can even set up all the other dependencies by Heroku provided Add-Ons.

It serves the purpose of many basic web applications. We can start out free but for anything with actual users, we definitely need at least Hobby ($7) or Standard Plan ($25+). On the Free plan, our server/Dyno will automatically shut down after 15 mins of inactivity. Any web request after will also re-start the server though but obviously will take longer than usual to respond. Also for Postgres Add-On, we will have a limit of **_10,000 rows_** and **_20 connections_**.  

They have good documentation on Getting Started.  Basically, after 3-4, Heroku CLI commands you will be able to see your application up and running. Once everything is configured, Uploading a new version or update is as easy as pushing a new commit to Heroku's git origin. You can view application health status from the Heroku web app. You can also view your application logs using both the web app and Heroku logs command.

### [Pricing](https://www.heroku.com/pricing): 
Heroku may get a bit expensive as our app grows for scaling needs. For our example app in Standard Plan and Hobby Basic Postgres, We would be committing approximately $34-$80/Month (single dyno/instance + Postgres).

One thing to keep in mind when using Heroku is that all the user uploaded/generated files have to be stored on some permanent storage out of Heroku. Heroku doesn’t provide users with a dedicated machine, we cannot use its server storage to save user-uploaded files. Every time a Heroku dyno (server) restarts, you will end up losing all your stored data. Only git committed data stays permanent.

**_Deployment Guides:_**

https://devcenter.heroku.com/articles/deploying-python
https://devcenter.heroku.com/articles/django-app-configuration

##**Digital Ocean (VPS) / AWS EC2 / Google Cloud Compute Engine:**

The next option is to set up your own server. Digital Ocean or Linode is affordable for this kind of setup.  We can get a **$10 (2GB / 1 vCPU)** / **$15 (2GB / 2 vCPU)** machine to host a decent Django App. 

I have used this option personally as it’s inexpensive. We can even install Postgres on the same VPS to save on monthly costs.

Hosting an app on VPS requires some level of digging with Linux/Bash tools. There are a couple of things that you would have to handle yourself when choosing this option. With Heroku, you didn’t have to know about all of these steps:


1. Install Django Application server (gunicorn/uwsgi)
2. Install Web Server (Apache / NGINX) for reverse proxy
3. Install Database (Postgres / MySQL)
4. Configure SystemD scripts to allow application/servers to restart if instance boots/reboots.
5. Configure Application Logging and manage Log Rotation.


The benefit of this approach is that you can set everything working, including dependencies at about half the cost but it requires you to have some technical experience with Shell/Bash commands. Also scaling our infrastructure is complicated in this setup as compared to our other options.

**_Deployment Guides:_**

https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04



##**AWS Elastic Beanstalk /  Google App Engine:**

ElasticBeanstalk is a service by AWS that makes deployment and scaling web applications for common frameworks/languages easier.  With AWS infrastructure, It is a convenient choice of use. Deploying the Django app on Elastic Beanstalk wasn't as easy and properly documented as it was on Heroku but like Heroku, It abstracts a lot of deployment details. It automatically manages the web and application server configuration. Developers can also access application logs using both AWS [ebcli](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install-advanced.html) and AWS console. Google also has a similar service called [App Engine](https://cloud.google.com/appengine).

There isn’t any separate charge for using the ElasticBeanstalk service in AWS. You will only be charged for the other underlying services being used.  In our case these services will be:

   1. EC2 VMs
   2. RDS - Postgres
   3. S3 (EBS uploads Django code here)
   4. AWS Load balancer (Required when AutoScaling Enabled)


With EBS, we can choose whether we want to commit to a “single instance” or we want AWS to handle auto-scaling for you. With auto-scaling enabled, AWS can automatically start or stop instances depending on the load on your application. 

AWS offers 3 different types of load balancer:

* Classic Load balancer
* Application Load balancer
* Network Load Balancer

We can use Classic Load Balancer because of its fixed pricing (i.e $18.25/Month) 

We will approximately be committing around $45/Month with a single instance environment. I have also shown the breakdown below:


| Service                      | Price |
|------------------------------|-------|
| EC2 - t3 small  (1 instance) | $15.6 |
| S3 and network pricing       | ~0.5  |
| RDS - db.t3.small            | $27   |




With auto-scaling enabled, our pricing will vary depending on application load.  We can even scale to 0 instances when auto-scaling is enabled. 

You can also **_apply for ["reserved instance" discounts](https://aws.amazon.com/ec2/pricing/reserved-instances/pricing/)_** by paying upfront or partial upfront costs of these resources.

Note: To avoid surprise billing, always add billing alerts on AWS.


**_Deployment Guides:_**

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-django.html


##**Conclusion:**

If you are a  beginner and want your Django app to be up and running as quickly as possible Heroku should be your go-to choice. Free and Hobby plans are great to learn and upload your hobby apps.  
 
If you have expected and consistent app traffic and are familiar with basic shell commands, we can set up our own servers using Digital Ocean VMs or EC2s. 
 
Lastly, Elastic Beanstalk (or App Engine) is a good choice if we are familiar with AWS infrastructure. It manages the app’s auto-scaling and load balancing requirements and makes deployment easier.
 
**_Note:_** All the estimated prices were at the time of writing and the purpose is just to give an overall cost analysis difference in each option.

There may be many other services/providers which I haven't covered in this article.  Please tell me about them in your comments below.