I wanted a place to host pictures of/for my family and friends since I don't post photos of us on social media generally.
Over the years, the site has become my Frankenstein's monster or as a friend said,
"the most over-engineered image-server of all time."
The site began as an AngularJS learning project in 2017, which I soon rebuilt as a Spring Boot monolith.
By late 2018, I had transitioned to a Spring Cloud microservice architecture with a ReactJS frontend.
When Covid-19 hit, the extra time at home during isolation gave me the opportunity to experiment and iterate on the project,
leading me to replace the Spring Cloud services with a Micronaut cluster. Today,
it is a NextJS site supported by Go micro-services hosted in Kubernetes... so far.
One thing I’ve learned along the way is that building something real forces you to dive into
the details that are easy to overlook or purposefully omitted in a lab setting or playground environment. When it’s your
own project, every architectural decision, security control, and operational challenge is something
you have to own and solve.
Because of that, I’ve always treated this site as more than just a personal project. My goal
is to make it as close as possible to an enterprise-grade application, both in technology and
security. It is a playground, but a serious one—where I get to refine best practices and
push my own engineering limits.
Finally, this site represents a body of work, serving as validation
of my resume.
Current Tech Stack
Front End
User Interface/Experience (UI/UX)
Service Name: mirror — a reference to Galadriel's
mirror in J.R.R. Tolkien's The Lord of the Rings, which shows each person who views it something different.
Description: mirror is a NextJS
application written in TypeScript using NextJS's App Router pattern. In short, this is the part
of the application that you can see and interact with directly.
Service Layer
The over-arching theme in these serivces is to use as few third party libraries as possible.
I spent the first half of my career using Java frameworks like Spring Boot and Micronaut,
which are very powerful and do a lot of things for you out of the box. My goal for this
iteration of my services is to learn build the functionality those frameworks provide, such as web calls and retries,
persistance repositories, authentication, encryption, etc.
To this end, I have written a stripped
down version of a web framework called carapace (because “exoskeleton“ was taken) to
provide reusable components, functions, and models for my services below. Also in carapace ,
I am slwoly building up CLI code/tools to perform tedious support and DevOps activities like cert rotation.
Service-to-Service Authentication (s2s)
Service Name: ran — rán (燃) is the name of one of two twin dragons
in Avatar: The Last Airbender. Ran (燃) means "burn" or "ignite" in Mandarin, and since all services
need to get service credentials before talking to any other action, the ignite side of the dragon pair
seemed appropriate.
Description: ran is an application written in Go,
utilizing my carapace project for core microservice functionality.
It provides service-to-service (s2s) authentication and authorization to the rest of the services in the cluster.
It mints s2s JWT tokens and it is the source truth of for JWT scopes in both auth services
(simply because the scopes table existed in this service first).
Identity (iam)
Service Name: shaw — shaw, or more correctly: shāo (燒), means "burn"
or "blaze" in Mandarin, and is the second of two twin dragons in Avatar: The Last Airbender.
Description: shaw is an application written in Go,
utilizing my carapace project for core microservice
functionality. It is the service counterpart to ran, providing user
authentication and authorization. It mints user JWT tokens and it is the source of truth for user identity,
though it does not contain all of a user's profile information.
Gateway
Service: erebor — Erebor is the proper name of The Lonely Mountain
from J.R.R. Tolkien's The Hobbit. It is where Smaug is sitting on his mound of treasure, i.e.,
this gateway will give access to the site's restricted content. Also, in the story, Erebor had a
Great Main Gate so I thought it fit.
Description: erebor is an application written in Go,
utilizing my carapace project for core microservice functionality.
It provides the main entry point to the website's backend functionality and restricted content.
It is more than a reverse proxy however, it manages user sessions, Oauth2 exchange flow, and JWT tokens.
Also, it assembles composite data from multiple services. It can be thought of as the site's primary service,
or hub, with the other support services coming off of it like spokes.
Persistance Layer
All of the service layer applications persist data to MariaDB databases behind the scenes.
Infrastructure
The UI and all of the service applications run in Docker containers, hosted in a
Kubernetes (k8s) cluster running on various old, busted computers at my house.