April 28th, 2019
Docker Part III: Containerizing an Application
In my previous two Docker articles, I explored container environment basics and created a playground to run Docker on AWS. In this article, I'm creating a containerized application that is publicly accessible from the internet.
April 1st, 2019
Docker Part I - Basic Concepts
When I worked on my first website saintsxctf.com during my senior year of college, it was a huge revelation that I could pay a company to host my website on their servers. The most surprising part for me was how they were hosting it. The web server was a virtual private server, which is a virtual machine (VM) sold as a service1. The VM ran a Debian Linux distribution. This means I wasn't paying for an entire bare metal server, instead provided a software program which acts like a physical server. In fact, there were likely many other virtual private servers running on the same hardware as mine.
The adaptation of virtual machines was a major milestone in software development history. Instead of needing a single physical server for each application, a single server could run a program called a hypervisor which would create one or many virtual machines. Virtual machines scaled as needed to match business needs. Eventually companies didn't need to invest in physical servers as cloud providers started offering VM IaaS (Infrastructure as a Service). An example of a VM IaaS is EC2 (Elastic Compute Cloud) on AWS.
April 8th, 2019
Docker Part II - Building a Playground Environment
In my previous post about Docker, I explored the basic concepts of Docker containers. In this post, I'm creating a Docker playground environment on AWS with Terraform and CloudFormation. The playground consists of an EC2 instance with Docker installed. It's accessible from the internet to facilitate containerized web applications. To start I'll discuss why I used Terraform and CloudFormation to build the playground. Then I'll take a deep dive into the infrastructure code.
September 24th, 2021
Creating Reverse Proxies with Nginx and Docker
Many of my applications contain frontend components and API components. These two components are loosely coupled but communicate with each other over HTTPS. For example, my saintsxctf.com application has a React frontend which communicates with a Flask REST API backend, along with other API Gateway REST APIs. One way to accomplish communication from a frontend to an API is by explicitly writing the URLs of the APIs in the frontend code. This works fine, but it also exposes information about API origin servers to clients. Origin server information exposure can be avoided by passing all API traffic through the same URL as the frontend application. This is accomplished using a reverse proxy.
The following image shows my SaintsXCTF website, and how the URL of the API is hidden from clients. If users inspect the website's network traffic, they see HTTPS requests sent to the reverse proxy server for saintsxctf.com, instead of the actual API server api.saintsxctf.com.
September 30th, 2019
Integrated Queries with LINQ and SQL Server
My previous article explored LINQ, a module that brings query syntax to C#. All the examples in that article queried local data structures. While using LINQ on local data is valuable in itself, LINQ can do much more. LINQ really shines when used to query remote data sources. Queries on remote data sources such as relational databases are known as integrated queries. In this article, I explore integrated queries with a SQL Server database. First I create the SQL Server database instance with Docker and then query it using LINQ.
September 29th, 2020
Jenkins Server Modern Infrastructure with Kubernetes on EKS
In a prior article, I discussed a Jenkins server I created on AWS EC2 and EFS. In this article I’ll discuss the second generation of that infrastructure, which uses Docker containers orchestrated by Kubernetes on an EKS cluster.
May 13th, 2019
Orchestrating Containers with Kubernetes Part I: Concepts
I recently wrote a series of articles on Docker and containerized applications. In those articles I worked with a single Docker container at a time. Each container was mapped to a port on its host machines IP, making it accessible from the browser. In my case, the host machine was an EC2 instance.
While the single container approach works, it has a number of limitations and drawbacks. First off, a single container isn't scalable. As web traffic to an application increases, the load becomes too much for a single container to handle. Secondly, there isn't a zero-downtime approach to release a new version of an application. The container running the old version has to stop and a container with the new version has to start in its place. While both these limitations are deal breakers in themselves, the worst part about the single container approach is that its a single point of failure. If the container stops or the application crashes, the entire website goes down. This makes deploying a production application on a single container inadequate.
May 20th, 2019
Orchestrating Containers with Kubernetes Part II: Single Node Cluster
In my previous Kubernetes article, I went over the concepts of container orchestration and the architecture of a Kubernetes cluster. In this article, I'm building a single node Kubernetes cluster that runs a Node.js application.
The Node.js application is the same one I used in my article on Containerization. The Kubernetes cluster environment is very similar to my Docker playground. The single node Kubernetes cluster is created with a CloudFormation template wrapped in Terraform. It installs Docker, kubeadm, kubectl, kubelet, and kubernetes-cni. You can check out the infrastructure code on GitHub.
June 14th, 2021
SaintsXCTF Version 2.0: Architectural Overview
On December 24th 2016, I released my first website saintsxctf.com. I was still a senior in college at the time, and used my limited software development knowledge from classes and a summer internship to build the application. SaintsXCTF is a training log designed for my college Cross Country and Track & Field teams at St. Lawrence University. Running competitively in college had a major impact on my life, and I was really proud to create the website to assist my teammates and coaches. Shortly after releasing the website, I created an Android application and an iOS application for SaintsXCTF. With SaintsXCTF accessible via web browsers and mobile applications, I felt my development work was complete and moved on to other programming projects.
As I began my professional software engineering career in the summer of 2017, I gradually learned industry best practices and became more well rounded as a developer. At this point, certain shortcomings and misguided assumptions about my SaintsXCTF applications became apparent. First, the core web application and API did not follow the latest industry standards. Second, all three applications were not properly tested and were prone to degradation if left unchecked. Third, the security & infrastructure of the applications was very basic and not fault tolerant. Lastly, my assumption that releasing the applications meant my work was done proved to be incorrect. As all software engineers know, the work just begins when an application is initially released.
July 31st, 2021
Building a GraphQL React Prototype
Last year, I started using GraphQL at my job. I decided to create some GraphQL prototypes in my spare time, to get better acquainted with the GraphQL ecosystem. In 2018 I learned the basics of GraphQL and wrote two articles about my experience, but never dove into using GraphQL in real world applications. The GraphQL React prototype discussed in this article along with my Apollo prototype are the beginnings of that production application journey. In the future, I plan on using GraphQL for the API layer of my applications.
The GraphQL prototype discussed in this article is a React front-end application that connects to a GitHub GraphQL API. The API provides details about my repositories, and React displays those details in a dashboard. The dashboard is shown below.
October 25th, 2021
SaintsXCTF Version 2.0: Kubernetes Infrastructure
The infrastructure for the React/TypeScript frontend and Flask/Python backend for my website saintsxctf.com is hosted on Kubernetes. My Kubernetes infrastructure is hosted on a cluster, which is managed by AWS EKS. This article outlines the Kubernetes infrastructure and walks through Terraform code which configures and builds the infrastructure.
March 27th, 2022
Running a MySQL Database Client on Kubernetes
In the first version of my SaintsXCTF application, one underdeveloped aspect of the technology stack was the MySQL database infrastructure. The only way to access the production database was to create a bastion host and interact with it via the command line. This bastion host was a server that was only accessible from my IP address and could only interact with my MySQL database. All other network ports were closed.
While this was an okay start, I really wanted a user interface to interact with the MySQL database with similar functionality to a local MySQL IDE, such as DataGrip. After researching different options, I decided to use phpMyAdmin, a MySQL administrative client that can run on a web server.