Personal Website

A personal website created using Django.

Why Make a Personal Website?

When I decided to make a personal website to display my resume and a portfolio of projects I have worked on, the intent was to help create a central location where I could chronical the things that I have done. It felt like a project that would take a lot of effort to implement initially, but once the work was complete it would always provide value (at a minimum as a reference for myself to remember and reflect). It could serve as a living proof that I can create a website, and that I'm concious of problems in the modern web design space: accessibility, responsive design, mobile performance, SEO, etc. As an added bonus, I deliberately used a lot of technologies I haven't used before, because I love to learn.

Choosing a Stack

I had recently done a lot of research on the modern offerings for web frameworks for a professional project, and this research proved useful in selecting a stack. I settled on using a Django based stacked, partially because of my interest in improving with python, and partially because it appears to be one of the best frameworks out there for building and maintaining a website focused on static content. Of particular interest were the built in security implementations such as CRSF protection and native sql injection protection, as well as the template system and administrative oferrings that would make maintaining and creating new pages a breeze. The decision of Django guided a lot of my further decisions. Since I didn't think the site would need to be a single page app and I wanted a simple design, I opted for a simple jquery and bootstrap front end. On the back end I used the common choices for Django, which is an nginx and gunicorn environment. With those choices made, the real adventure began, because my next goal was to create an automated build pipeline to get a sense of what a modern build environment would look like.

An Odyssey in System Administration and Devops

One of the biggest learning experiences in creating my own website was in the spaces of system administration and devops. I've setup LAMP stacks in the ancient past, and I've dipped into the system administration world at times to troubleshoot deep rooted issues, but for my own website I wanted to build a stack that I personally would like to maintain long term. From an administration perspective, this meant learning a whole miriad of tools I've never worked with.

Learning to Love Docker

The first stage of this journey was overcoming a healthy fear of Docker. I've heard the word Docker a lot, and have lived mostly in a world of VMs, but after building my environment around docker and docker compose it is difficult to imagine living without it now. I setup slightly varied docker environments for development, staging, and production, and then got busy learning how to create a build pipeline.

Entering The World of CI/CD With Jenkins

I had been doing some reading and research on CI/CD pipelines and their best practices, so I wanted to implement a CI/CD pipeline with this project.  The CI server I settled on using was Jenkins, because it seems to be one of the most widely used open source CI tools. I started off with one monolithic pipeline that built the website and all the server configuration, and deployed it through to my staging and then production server. After a few weeks, I decided I wanted to reuse a lot of the configuration for other projects, so I eventually split out the pipeline to utilize parameterized builds, and split the website and configuration into their own separate projects. So far this has worked well, since I'm able to build individual projects on their own, and then deploy them without making significant changes to other projects already running on the server.

Connecting Everything Together in AWS

I had used some of the AWS offerings in the past, but this became my first proper exposure to a more comprehensive AWS environment. First I setup the production environment in an EC2 instance. From there, I created a second instance for the staging server, and ran jenkins on this server so that it could double as the build server. I setup the database instance in RDS, and connected it to the production instance, and then used ECR for storing all of the docker containers. With this setup, whenever I wanted to work on things, I could spin up the staging server to do a deployment, and otherwise the staging server could be left offline to save on having to run multiple aws instance. I now had a full fledged push button deployment process setup.

The Final Bits and Pieces

The last parts of building the site involved tying up some of the lose ends and doing some of the configuration that, having never had a production website before, I had never had to deal with. This included setting up and configuring a domain name for the site, as well as configuring https to work and purchasing an SSL certificate. Also included with this was learning a bit more about nginx configuration to make it so that I'd be able to run multiple different projects under the same domain.

Overall this ended up being a very useful learning experience, and gave me a deeper appreciation for what goes into creating a full fledge development environment. If my goal from the start was just to make a website as quickly as possible, I definitely would have followed a different path, but instead I tried to build a website using tools that modern web teams leverage to address the difficulties of scaling a website.

Epilogue

After a year of running the site on AWS by utilizing offerings from the Github Student Developer Pack, I began getting the bills for the environment I had created. The cost of using AWS proved to be too much for my needs, and I opted to migrate everything over to a Digital Ocean droplet instead to have a more predictable and reasonable cost. In this migration, I also replaced Jenkins with Gitlab CI/CD, and have found that the offerrings are much more appropriate for my needs. In particular, Gitlab CI allows me to use my own desktop to perform builds and deployments, and also provides its own container registry, which significantly reduced some of the barriers that existed in my jenkins build pipeline. I also moved my database out of RDS, and setup my own backup process to ensure I would have recovery plan should anything happen to the data.