Hosting my Django Website
Setting
I've been working on a photography website as a project to force myself to actually learn Django. I enjoy coding and I love taking shitty photos but I've never deigned to host my own work anywhere other than Instagram. By setting a project for myself like this, not only do I hope I become less sucky at working with Django, a necessary skill in my particular role at my workplace, one ancillary outcome is that I get to host my photos somewhere more permanently.
The progenitor website starting page
It has three views.
Starting page: Shows the three most recent photos
All photos: Shows all uploaded photos
Photo detail: Displays a single image with white margins
That's all it does right now. The photos are currently placeholders, They are my photos and they will appear in the final product but these particular photos are jpegs that have undergone at least 2x rounds of edits (jpeg's lossy compression gets applied for every edit + save). To be honest, they look fine to me but I'll want make sure the final product looks as good as I can make it. All static files (like the photos) are hosted locally for now. The plan is to put them in an S3 and get Django or Nginx to fetch them.
Photo detail view
Resourcing
Deciding on hosting raises some conflicting feelings. I want to take advantage of my somewhat working knowledge of AWS systems... but I also don't want to over-engineer this site that will likely only be visited by myself, my wife and a handful of job recruiters that actually vet me. I've never actually done this before either. So I'm not taking any shortcuts, nor am I jumping into architectures I have absolutely no business using.
Resourcing initial ✨idea✨
This is the basic plan. Chuck it on a tiny EC2. SQLite database to hold all the photo details including the S3 key (so it knows where to reach for it in the S3 bucket). The S3 bucket is just a regular bucket with public access blocked. I'll need to allow the server to access the photos on it via API key. Lets flesh this out a bit.
Resourcing ideal version 1
So I'm just using SQLite. This is a file-base database system. No need for a dedicated server which simplifies deployment drastically. The drawback here is that it's not quite as fast as a dedicated DB server like Postgres or MySQL would be. So I might have some delays in fetch times as the website grows. However, at this scale I think this will be fine. Similarly, hosting my photos on an S3 bucket means no need to spin up an additional private server. S3 is by far the cheapest option for file storage (probably) and the drawbacks are outweighed at this stage by my chief desires to spend no money and do no work.
First Deployment
My Django website's Elastic Beanstalk environment overview
Alright, I'm cheating. I'm using a barebone Elastic beanstalk application to spin up my EC2 in an "autoscaling group" of 1 instance, no DB, no VPC, no security groups. Just what is needed. In defence of my laziness, this is all I need at this stage. I wanted it live. It's now live (almost)
Deployment Woes
Right off the bat I ran into some problems getting a response from the EC2 instance deployed by elastic beanstalk. After re-deploying 4 times, re-checking my configuration each time, I was fed up. I've been working in AWS too long to get stuck at first deployment. Let's diagnose.
Elastic beanstalk is telling me it's deployed the EC2, added an EIP and added the EC2 to the environment. Good... So what's wrong? The problem is that AWS is getting no responses from the instance. Not just from the Nginx server, but from the whole instance. That tells me it's not connected to the internet. Lets check the instance settings.
Django website app EC2 instance Networking tab
Seeeeems fine... I didn't set any VPC settings so Elastic Beanstalk has taken care of all that for me. Let's look at the VPC and see if it has an Internet gateway.
Internet gateway generated by Elastic Beanstalk
Okay... is it routed?
Route table generated by Elastic Beanstalk
So that's weird right? There should be a route there for outbound packages (anything not going to 172.31.0.0/16). But there's not. Elastic Beanstalk generated everything I asked and then some, but stopped short of actually connecting the VPC to the internet. Let's add it in manually.
Route table with added route out to the internet gateway
I'll cut to the chase. That solved the issue. With my instance now connected to the internet, Elastic Beanstalk is getting responses and I'm able to connect on the default domain it's given me.
I'll leave it there for today
Literally best website you've ever seen
After adding the DNS entries for my domain and sorting out SSL, my site is officially on the web. I'm putting out my dirty html for the world to see. Instead of S3 hosting the images, the Nginx server on the EC2 is currently serving the sample images I loaded in with the code. I have many tasks left to do, but for today, this is enough.
Subscribe to my newsletter
Read articles from Samuel Drew directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Samuel Drew
Samuel Drew
I am a developer from Brisbane. Now living in Wellington. I've gone from a degree in software engineering to a career in traditional engineering and then back again to software engineering as a DevOps and Cloud infrastructure engineer. I love learning how things are made and I try to simplify things down to understand them better. I'm using hashnode as a blogging platform to practice my technical writing.