What better way to start this blog than by walking you through my goals and the process of selecting technologies for it. The final setup is simple, but we’ll get to explore some fundamentals of web development along the way.
Goals
This blog should be easy to maintain and very low cost. If I don’t post content for 3 months, I shouldn’t be worried it’s down or that I’ve run up a massive bill.
All of my supporting infrastructure should consist of simple, fundamental building blocks. It should be easy to replace any service with another and not be locked into any particular vendor.
Leverage just enough framework to consistently style and create blog posts quickly. However, I also wanted to ensure that what I picked could grow to support experimentation and other web projects over time.
I keep all of my notes in Markdown, and I wanted the same for my blog post content. This also supports another goal: keeping all content framework-agnostic to allow for quick switching if desired.
Creating a website
Websites are composed of HyperText Markup Language (HTML) and Cascading Style Sheets (CSS), which seed the Document Object Model (DOM) that is rendered for the user. In addition, the DOM can be manipulated using JavaScript to change or augment behavior.
However, the way these elements are used changes your approach to web development. Static websites are primarily compiled to HTML/CSS at build time. Server-side rendering (SSR) means that the site is compiled into HTML/CSS files on a server at request time before being served to the browser. Client-side rendering (CSR) uses a bare HTML page and then uses JavaScript to manipulate the DOM into the site.
All of these different kinds of sites can also use API calls to dynamically fetch content for the page or send data back to a server. In addition, Static and SSR sites can also use JavaScript, but they do not rely on it for all rendering like CSR does.
For a basic blog, though, we have almost all of our content ready at build time, so a static site will work great.
What infrastructure do you need to run a static website?
A DNS record, a signed certificate, a web server, and probably a Content Distribution Network (CDN).
DNS record
You don’t technically need one, but would you rather type in an IP like 104.21.25.252 or bhog.dev, given the option? The Domain Name System allows us to associate simple names with IP addresses to make browsing easier.
When selecting a DNS provider, one of the first things to consider is which domains they support. Almost all providers will support popular domains like .com, .net, or .org, but you’ll have to check if you want a less common one.
You can see some of the most popular DNS providers here.
Another thing to consider is cost: more popular names and domains demand a higher yearly registration fee or may already be taken.
For this blog, I wanted to keep my costs fairly low without resorting to commonly used spam or malware domains.
Signed Certificates
How do I know that the website I’m on is actually who they say they are and that my traffic is secure? The answer to both of these is an End Entity TLS Certificate signed by a trusted Certificate Authority.
How you obtain this certificate will depend on your web server setup and any other use cases you may have. In many cases, the solution you pick may handle this by default.
Learn more about TLS Certificates…
Your website’s certificate will contain a lot of information, but the most important for verified secure traffic are the dnsName, public key, issuer, and its signature.
The dnsName should match that of the website you are trying to reach. This ensures you can’t use just any certificate; it must be one for your website.
The public key was generated from the private key that belongs to you (or a provider you trust) and is kept secret. In asymmetric cryptography, we choose a mathematical operation that is very easy in one direction but extremely hard in the other. So anyone with the public key can verify that a signature was created with the private key. However, it would be extremely hard for them to create that signature without the private key.
So when you visit my website, you know I must have the private key by asking me for a signed message that you validate with the public key. But just because I have the key, why should you trust it? I could have simply created this certificate myself and signed it myself.
This is where the issuer and signature of the certificate come into play. When creating this certificate, I went to a trusted entity and asked them to sign my certificate using their private key, which I then attached to this certificate.
Using the same methods described above, you can verify that the signature on my certificate came from the issuer I claim by using the issuer’s public key. This issuer may themselves have been signed by another issuer, and so this process continues until you identify an issuer that you trust.
Oftentimes, this is a root Certificate Authority pre-installed on your user’s operating system. The creator of the operating system (Google, Microsoft, Apple, etc.) takes on the responsibility of vetting these root CAs.
Shown below is the certificate chain for this blog, which ends in a Google Trust Services root.
So we have verified that we are who we say we are and can trust each other. Now, to secure our traffic, we need to use symmetric encryption, which requires exchanging a shared key.
The client generates a random key, encrypts it using the server’s public key, and sends it to the server. Only the server with the private key can decrypt it. Now, with a shared secret, symmetric encryption begins and your traffic is secure.
There is a lot more going on with TLS certificates and the handshake process, but that is beyond the scope of this post.
Web Server
The final part of your site is a “server.” This server makes your static assets available on port 443 (or 80 if unsecured, which your site shouldn’t be).
If you are securing your site, this server may also host the certificate you created above and perform TLS handshakes with clients.
While this is the bare minimum, we ask for a lot more these days. We want caching, analytics, logging, threat detection, high availability, API routes, reroute rules, etc.
Oftentimes, this isn’t a single server or system, but a system of systems.
A common setup for an enterprise solution might be a high-availability API Gateway that sends requests to a load balancer, which selects a web server (NGINX is a popular solution) to serve the site. This might be backed by separate solutions for logging, analytics, and more.
Content Distribution Network (CDN)
A CDN is a network of servers that caches your site’s static assets closer to your users. Someone in Singapore doesn’t want to wait 5 seconds for an image from your site hosted in the United Kingdom. In addition, large assets like images or videos can be very resource-intensive for your web server to distribute.
A CDN isn’t always needed, though, depending on your use case. Imagine you run a website internally for your company; in most cases, the users are likely in the same country, or you may not want to expose your site to the global internet.
Choosing technologies for this blog
So now that we know what we need, I looked at domain costs. They ranged from $1,000 per year (.inc) down to $2 per year (.xyz), and many in between.
I settled on .dev as a good-value domain that was tech-related and went to a DNS provider to register it. In this case, I checked AWS Route53 first, which I’ve often used. I would also be able to distribute my site using AWS CloudFront, a CDN. Certificates could also be provided with AWS Certificate Manager.
However, .dev isn’t a supported domain with AWS Route53… Sticking with the goals, though, we aren’t using anything provider-specific, so on to the next provider.
Cloudflare supported .dev domains via their DNS solution and is a very popular and well-liked option. They also have their own CDN and provide certificates in their free tier when you purchase a domain.
The last thing I needed was a web server. Initially, for this site, I don’t have any API or dynamic asset needs. So my web server just needs to seed my static assets to my CDN.
Most major blob storage services provided by cloud service providers like AWS, Azure, or Google can be used as a static web server for very low cost, if not free.
This also means that to deploy my static site, all I need to do is sync the build directory with my blob store.
The last part I needed was the actual website itself. I knew I wanted a static website framework that met my goals, and there is a whole architectural philosophy for sites like this (Jamstack)!
There are hundreds of static site generators for you to choose from: https://jamstack.org/generators/. All have different strengths and weaknesses for different kinds of sites or might use technologies you are more comfortable with.
I started searching for what would best meet my needs and quickly came across Astro. I found it supported all of my stated goals for this blog. Hugo and Eleventy were other contenders I might pivot this project to one day or use for others.
There are also hundreds of templates for Astro blogs to use, modify, or get ideas from, which led me to Mark Horn’s great Astro templates!
In the next post, we’ll step through an actual tutorial to get our infrastructure set up and deployments automated.