Design and deploy your Django-React web application on AWS
Let’s talk about how you’d host a web application with Django as the backend, React for Frontend and hosted on AWS. We will be covering most aspects of this application from provisioning AWS infrastructure and Networking to configuring DevOps activities such as CICD on a high level.
Let’s just dive right into it.
The contents of this article are:
- Networking — for setting up the infrastructure
- Architecture — Various components and Information flow
- Frontend and CDN
- Autoscaling and load balancing
- DevOps and CICD
First of all, we’ll set up the networking by provisioning a VPC that will contain public and private subnets.
At a high level, our infrastructure will have EC2 instances and a database cluster that will be hosted in dedicated private subnets and additionally we’ll have Load balancers, NAT Gateways as part of the public subnets. You’ll need a sound knowledge of Route tables to have reliable communication within and outside your network.
These subnets will be distributed across 2 availability zones for better availability.
Bonus tip: Have a CloudFormation template or Terraform module for the VPC configuration so that it’ll be easy to set it up across multiple environments and across similar other projects as well.
Here’s how the complete architecture looks. We will discuss each part one by one.
We will have EC2 servers to host our Django backend. You could have it as a containerized service with ECS/EKS, but if you are not familiar with all that and want to start simple, EC2 would be the best option.
As we have a headless frontend here, our Django application will be mainly used for hosting APIs instead of directly serving templates.
You can run your Django application with uWSGI or Gunicorn setup along with NGINX for a production-ready system and better reliability.
If you are using AWS, RDS would be the way to go. The most common databases to use along with Django are PostgreSQL or MySQL databases but you can choose based on what suits you the best. Go with PostgreSQL if you don’t have a preference.
Working with Django helps really well if you do not want to interact with the database through SQL queries as it provides a very feature-rich ORM. You’ll just need to do database migrations as and when you make changes to your Django models and that’s it.
Frontend and CDN
I would say going with a headless approach with your Frontend should be best, especially if you have multiple Frontend applications using the same Backend. For example, an e-commerce storefront and a content management system for the admins.
Using CloudFront will also help you with the latency and your Web App will load lightning fast. It also gets easier when you want to enable SSL/TLS in your application as it provides easy integrations with Amazon Certificate Manager(ACM). This way no one would see the not secure tag on your web application.
For communication between the frontend and backend, going with Django Rest Framework for creating APIs would be the most efficient way to go.
Autoscaling and Load Balancing
While S3 and CloudFront’s global infrastructure can help you scale your frontend pretty easily, you’d still need to have AutoScaling in place for your Django backend.
As part of the AWS ecosystem, you’d get an awesome pairing of AutoScaling groups and Application load balancers to cater to your scaling needs. These services provide easy integration with each other as well as with EC2 servers.
With AutoScaling groups, you will use features like scaling policies to define how you’d like to scale your application. The most common metric to use in these cases would be to put scaling based on the average CPU utilisation of the servers.
Application load balancers also provide features like path-based routing, SSL termination, stickiness, and automatic health checks in addition to actually balancing the load among your servers.
DevOps and CICD
Finally, few points to consider looking from a DevOps perspective:
- Use infrastructure as code from the start of the project. It’ll help you when you progress with the project and the need to manage multiple environments will be more. It’ll also help you move to production faster. Using CloudFormation/Terraform should be good here.
- You’ll need to set up CICD for both your backend and frontend. If you are just using AWS for everything, native CICD tools would be the easiest to set up and are cost-efficient. They’ll also provide easy integrations with other AWS services, for example, you can deploy your frontend to S3 via CodePipeline as soon as you build the React App in CodeBuild.
- You’ll also need to handle Django migrations in the backend pipelines. Try to integrate unit testing in the CICD pipeline itself.
- When deploying changes that require both frontend and backend to be deployed simultaneously, try to tie up the CD part of the pipelines or as a workaround here, simply put approval stages before the end steps, and approve both together.
- Enable application logging to CloudWatch or any custom logging service. This will help you diagnose issues faster and will also help you with logs and metrics for servers that are no longer available, basically giving a persistence space for your logs. Moreover, you'd be able to create insights and alerts based on these logs.
- You’ll have to configure the Database configuration as well, based on the load you’ll have. Scaling the database might have some downtime and if you can’t afford the downtime in production you can explore the option of using an Aurora database instead of plain RDS, which will give you a close-to-serverless experience with negligible management overhead. Keep in mind the costs though, try to calculate everything beforehand.
That’s it for this Article. We have covered a lot of ground on a high-level system design and this will serve as a good starting point for your web application. What we haven’t covered is security, containerisation and some minute details while building the design. Each part here can be deep-dived along with some sample code, but that’s for some other time.
Feel free to reach out to me for more details at firstname.lastname@example.org or follow CodeByte on Instagram.