How I Built This Site


Published: 2025-03-21
Last updated: 2025-03-21
Reading time: ~3 min
Tags: elixir phoenix

If you're like me, you love to learn about the stack behind the apps and websites you come across. How does it really work and what pieces are involved? What tools were used? How was it designed? I'll be answering those questions about this site below.

Context

Building my personal site was on my TODO list for a long time. I wanted an online presence where I could post writings, share projects, and use it as a sort of web playground. I built (and rebuilt) this site at least 4 times with different programming languages and tools, the first being Clojure. Each had their pros and cons, but none felt like a good fit for me. I knew I wanted to build it myself without any ready-made tools like Squarespace or WordPress. I wanted flexibility and customization without too much complexity. I eventually settled with Elixir/Phoenix because it allowed me to get going fast, handled much of the request-handling complexity, and allowed me to be productive and focus on the fun parts.

The Stack

This site is built as a standalone Elixir/Phoenix front-end which sources pages and posts from my Ghost CMS in the back-end, where I write and manage all of my content. This way, I have clear separation between the development of my website and its content. I picked Ghost because it seemed the most streamlined and easy to get going with for my use case (I am running it with their official Docker image). They also have a great content API and great docs.

When it comes to Full Stack Development, I would have to admit that front-end styling is my least favorite part. I wanted something clean, elegant, minimal, and super easy to work with. PicoCSS was the clear standout winner when looking at my options; it also came with Dark mode built-in. I value the emphasis on semantic HTML and minimal classes only when needed and it is my preference over class heavy CSS frameworks. You might now be wondering why then I mentioned that I am using TailwindCSS in my stack, which is inherently class-heavy. Phoenix projects by default include Tailwind integration so I kept it for that reason and use its utility classes when needed where PicoCSS doesn't reach. That way, I can get the best of both: clean, semantic HTML pages with useful classes littered in where I need them. If you are accessing this site on a desktop computer, you may have noticed the Theme Changer dropdown in the navigation menu. You can conveniently change the theme of this site and play around with different retro styles (themes by tdiary). This feature is only enabled on the desktop version of this site, since tdiary themes are not mobile-friendly.

For deployment, I thought about different options like Fly.io, but wanted to keep costs down for my simple use case and felt that it would not give me the most value to deploy my code on some managed platform service. I decided to go the traditional route of running a small, low-cost VPS and manage all of the deployment details myself. This way I could also run other projects and web apps on my server and maximize value. There are plenty of VPS providers but I went for LightSail as a way to get my feet into the AWS ecosystem and gain some experience with it. They also had decent specs for their lowest cost VPS and a 3-month trial with the free tier. I also really appreciate the clean management console. My code is packaged into a Docker image which I simply pull and run on my VPS whenever I am ready to go live.

My server runs Debian for the OS. I use Caddy as my reverse-proxy web server because of the simplicity. I've run plenty of other web apps behind Nginx in the past, but wanted to try something new.

Wrapping up

That pretty much covers everything behind the scenes on this site. I hope that it has been beneficial. I am working on other projects right now so stay tuned for more tech stack breakdowns.