This repository is the outcome of a week-long code sprint to teach myself how to make a production website using several different DevOps and deployment tools.
The base e-commerce site here is from the great Udemy course Django with React | An Ecommerce Website. The goal here is not to make a "real" e-commerce site but instead to give a real-life example of deploying a system to production.
Developing this project was a great learning experience and one day I hope to turn it into a more formal course/blog post/video or something. For now I'll give an overview of the technoligies used and how they fit in to the overall production system.
The base e-commerce site here used Django with the Django REST framework and PostgreSQL for the backend and React using Redux for state management for the frontend. Following the course, I also use AWS s3 buckets along with WhiteNoise to store and serve user-uploaded media files. Other than a few small changes the basic website and code is exactly the same as the Udemy course. I had never used Django or React so I just wanted to follow along.
Once the basic site was build the next step towards production was to containerize the application. To do this I used Docker to containerize the backend
and frontend. For the frontend I created a "development" and a "production" container. The development container just runs npm
as you would normally during development and allows for hot-reloads. For the production conatiner I used NGINX as reverse-proxy to handle the communication between frontend and backend.
To handle the networking and connections to the Postgres database I used Docker Compose creating both a dev and production deployment.
Depending on the usecase, this could be the end. You could deploy with docker compose on EC2, Heroku, etc. But I wanted to go further...
Even the basic web application requires an s3 bucket to store the media files. Of course we can follow the web UI and just create an s3 bucket but I wanted to devopsify this thing.
I took another great Udemy course Complete Terraform Course - Beginner to Advanced on terraform and I wanted to try it out. Let me tell you, you will feel like a freakin wizard after using terraform!
For this project I needed a few AWS resources. First, I needed the s3 bucket to host and serve the media files, but I also wanted to store my Docker images in AWS ECR and I also wanted to use Github Actions to build and push the web app Docker images. So that is what I did:
- s3 bucket for media files (+ a bit needed for Kubernetes...)
- ECR resources for Docker images
- Github Actions user with minimum required permissions to push to ECR
A last note on terraform and AWS. If you want to learn about IAM deploy some resources with terraform. Way more explicit than using the web UI.
Ok, I wanted to use terraform for setting up an configuring an EKS but it was a bit daunting. Instead I used eksctl which is another IaC tool but a bit more high-level than doing it with terraform. I have written some (incomplete) instructions here on how this is used to setup our EKS cluster. Just to note, I also had to add a custom role in AWS so the EC2 worker nodes can access the s3 bucket that stores the media files.
Getting things deployed with Kubernetes took a bit of trial and error. As an overview I used Kustomize to configure the deployment. For this app I didn't separate out dev and prod but it is still good practice. I also used the NGINX Ingress to manage the communication and entrypoint into the web application.
Because I love automation and the idea of GitOps (git repo is single source of truth), I wanted to try out Argo CD. Because we are using multiple kubernetes deployments I used the "app of apps" setup so that we can make sure all of our services are deployed. By deploying Argo CD in the EKS cluster and configuring it to look at this repo, it will make sure that whatever kubernetes manifests are in this git repo are the ones deployed in the EKS cluster. So once everything is setup you just have to change the yamls in this git repository and your changes will automatically be deployed. Awesome! You can see it deployed here (it is shut down now because AWS is expensive!):