1. Context
2. Software Architecture
3. Deployment
4. Decision Log
4.1. ADR 1 – Static Website
Date: 2023-01-03
4.1.1. Status
Accepted
4.1.2. Context
There are many ways to blog on the internet. You could post articles to social platforms like LinkedIn. You could post articles to platforms like Medium or Dev.to. You could get your own website using services like Wordpress that provide hosting and complete themes for blogs. Or you could build a website yourself.
Goals and Principles
My top quality goals for this website are Performance Efficiency, Reliability, and Portability (see Building a Blog: Quality Goals).
Make or "Buy"
Posting articles to platforms like LinkedIn, Medium, Dev.to, or managed Wordpress gives you reliabilty – no operations or maintenance effort necessary. But the platforms lack portability. You can’t easily port the blog to another platform. You would have to copy & paste all articles.
Building a custom blog can achieve the performance, reliability, and portability goals – depending on how you build it.
Static vs. Server-Rendered
You can build a custom blog as static website, where the HTML/CSS/JS/… files generated at build time, and then stored "on the web" in a CDN or S3-like storage. Or you can render the pages dynamically on a server (and optionally cache them).
Static websites can’t render pages dynamically per user. But they bring some benefits (see Why Jamstack?):
-
Security: Immutable files without server or database access provide a minimum attack surface.
-
Scalability: Static websites can be served by a CDN, which can withstand even DDoS scenarios.
-
Performance: The markup and assets that the clients request are generated at build-time.
-
Maintainability: Serving static assets reduces operations effort to a minimum. This supports high availability.
-
Portability: You can host static files anywhere.
4.1.3. Decision
I will build the website as a static site.
A static site can achieve the top quality goals. Serving static files is fast and cheap. It requires minimum operations and maintenance work. It can be hosted anywhere.
4.1.4. Consequences
A static website will be simple and durable. It will give me freedom for design and technology choices. It will allow me to play around with different technologies and techniques.
It takes some effort to design and build a website – significantly more than just posting articles to other platforms. However, it is easy to get started with: there are many templates for blogs that are quick and easy to set up. The design can come later.
A static website will not have the kind of virality of popular platforms. When I publish an article to LinkedIn, I might get around two thousand impressions on people’s feeds. By comparison, this blog will be read by virtually no one. With a custom website, you can still cross-post the content to multiple platforms or just link to the website from platforms like LinkedIn. However, platforms like LinkedIn might not spread posts with outgoing links as widely.
4.2. ADR 2 – Content in Git
Date: 2023-01-04
4.2.1. Status
Accepted
4.2.2. Context
I will build this blog as a static website (see ADR 1. Blog posts require formatted text content and assets like images. That content has to be stored somewhere.
The simplest approach is to store content and assets directly in the repository. Text can be stored in Markdown files. Images can be stored in an assets folder. Editors like Visual Studio Code can show a preview of the content of Markdown files. For a single editor, who is used to git and who can preview the full site on their local machine, this works. Github repository limits are generous enough that small images that accompany articles should not pose a problem (see Repository size limits for GitHub.com). Largers assets could be stored in some S3-like storage service.
-
✅ Service-agnostic: Markdown is a standard format
-
✅ Avoid 3rd party service: does not depend on existance and pricing of service provider
-
❌ Content in repository: can clutter up and enlarge repository with assets; assets in public repository?
-
❌ Requires technical expertise: Markdown and git are required to edit content
On the other end of the spectrum, you can use a CMS-as-a-service from providers like Storyblok, Contentful, and others. They provide editing and publishing features on the web. When content changes, a web hook triggers a build. The build process gets the updated content from the API of the service. The services facilitate content management with multiple editors (including rights management and configurable publishing processes). The services typically support image content and other assets. They typically provide a CDN to serve the assets to clients. By focusing on integration via their APIs, the services work well for static websites.
-
✅ Best editing experience: services provide elaborate UI
-
✅ Content and assets separate from code: repository stays lean and assets don’t end up in public repository
-
✅ Support large assets: services are built for managing and serving large assets
-
❌ Dependency on service provider: service provider may go out of business or change their pricing/plans
-
❌ Non-standard format: service may store text content in a proprietary format that can’t easily be ported to another service
Between the two extremes, there are git-based CMS solutions like Tina. They can provide an editing experience comparable to the CMS-as-a-service approach. But all content stays in git.
-
✅ Good editing experience: can (theoretically) provide editing capabilities comparable to CMS services
-
✅ Service-agnostic: Markdown is a standard format
-
✅ Avoid 3rd party service: does not depend on existance and pricing of service provider
-
❌ Content in repository: can clutter up and enlarge repository with assets; assets in public repository?
4.2.3. Decision
I will store content and assets directly in the git repository using Markdown for text content.
One of the architecture principles of the website is "built to last". Using standard formats and avoiding a 3rd party service supports that.
I don’t expect to create so much content (and use so many assets) that github repository limits would become limiting.
I will experiment with a git-based CMS solution that relies on Markdown. I don’t expect any benefits for my use case, but I would like to gain experience with git-based CMS solutions.
4.2.4. Consequences
Relying on the standard markdown format and avoiding a 3rd party service supports the architecture goals of this website. It should be built to last and portable to other providers.
Experimenting with git-based CMS solutions will allow me to use the website as playground for learning.
Keeping the assets in the repository could become cumbersome. In rare cases, I might want larger assets like audio or video files. I would not want to add them to the git repository but use another storage option like an S3-like service instead. Therefore, I might not treat all assets the same way – adding some inconsistency.
4.3. ADR 3 – Astro on Cloudflare
Date: 2023-01-05
4.3.1. Status
Accepted
4.3.2. Context
Static Site Generators
There are many Static Site Generators (SSGs) and, more generally, meta frameworks that can generate static sites (see Site Generators).
Popular classic site generators include Eleventy, Jekyll, and Hugo. They specialize on static sites. Over the past few years, SSG has become a common feature of most meta frameworks. They include Next, Nuxt, SvelteKit, SolidStart, Qwik City, and more. Most meta frameworks are built for a specific component framework. Astro, on the other hand, supports a number of popular component frameworks. It started out as a Static Site Generator and was later extended to also support server-side rendering.
Single-Page Application vs. Multi-Page Application
A key difference between the Static Site Generators is whether they produce Single-Page Applications (SPAs) or Multi-Page Applications (MPAs).
SPAs can achieve an app-like user experience with quick navigation between pages. However, that comes at a cost. They tend to use significantly more JavaScript, which reduces first page load performance. SPAs also present some additional challenges for accessibility due to their client-side navigation.[1]
Frameworks like Astro and Qwik City have overcome some of the biggest challenges of the MPA architecture. They enable a more seamless developer experience between the static parts of a website and the interactive parts.
Hosting Static Websites
There are many platforms for hosting static websites. Popular examples are Netlify, Vercel, Cloudflare Pages, Azure Static Web Apps. They provide similar capabilities and are easy and cheap to use – with generous free plans.
Most platforms for static websites provide Github integration, where commits trigger new builds. Branches may automatically be deployed to a preview environment / URL. The platforms can manage custom domains and provide SSL certificates automatically. Some platforms differentiate themselves through integrations with other services like data stores or server-side analytics.
For basic hosting of static websites the different platforms appear similar and it should be easy to move a website between different platforms.
Goals and Principles
My top quality goals for this website are Performance Efficiency, Reliability, and Portability (see Building a Blog: Quality Goals).
4.3.3. Decision
I will build the website with Astro and host it on Cloudflare Pages.
Astro is a part of the recent renaissance of Multi-Page Applications. It enables creating lightweight pages with little JavaScript and fast first page load performance. This is in line with the quality goals of this website.
Another benefit of Astro is that it does not lock you into one component framework. It supports a number of the most popular frameworks. Being able to experiment with different frameworks supports my goal of using this website as a playground for learning. The increasing popularity of Astro also makes Astro experience valuable.
Cloudflare is one of the leaders in the area of edge computing. With their leading CDN and their growing list of edge services like Cloudflare Workers and various edge data stores, they provide a lot of opportunities for learning.
Cloudflare offer Cloudflare Pages[4] with a generous free plan[5]. That includes free web analytics and unlimited sites/requests/bandwidth. As long as you don’t need more than 500 builds per month or concurrent builds, this is enough. Besides hosting static websites, Pages also provides integrations with other Cloudflare services like Workers. It also enables server-side rendering "on the edge".[6][7]
4.3.4. Consequences
Astro supports the goals for performance and portability. It will not lock me into a specific component framework and will produce fast pages with little JavaScript.
By working with with a popular, trendy framework and a popular leading platforms, I will have ample opportunity to experiment with interesting technologies and gain valuable experience.
There may be some tension between the goal of portability and treating the website as a playground for learning. While it is trivial to move basic static websites between different hosting platforms, integrating platforms-specific features like edge data stores could reduce portability.
4.4. ADR 4 – Documentation as Code
Date: 2023-01-23
4.4.1. Status
Accepted
4.4.2. Context
Lightweight Architecture Documentation
Large documents are never kept up to date.
Small, modular documents have at least a chance at being updated.[8]
Documenting Architecture Decisions
Software systems typically benefit from some level of documentation. For most systems, the sweet spot is lightweight documentation that you can create and maintain with relatively low effort.
Architecture Decision Records (ADRs) document significant design decisions for a system. They record the decisions with their context and motivations at the time the decision is made. They are immutable – they do not have to be updated, but they might be superseded by later decisions.[9][10]
C4 Model Diagrams capture the high-level architecture of a system. They contain enough detail to get an overview of the system without further explanations: they contain the descriptions of the building blocks and their relations, as well as information about the used technologies.[11]
Documentation as Code
The idea of documentation as code is to maintain the documentation together with the code in version control. The developers can work on the documentation and code in their IDE with little friction from switching tools. The documentation can be built and deployed to the desired format and location much like the application itself.[14]
AsciiDoc and Markdown are popular markup languages for writing texts in a plain text format with special syntax for formatting, layout, links, and more. The two formats are comparable, but for documentation it helps that AsciiDoc is standardized and more exensible than Markdown. [15] [16]
Markdown is a concept more than it is an implementation. It generally means “a set of incompatible extensions to something that looks kinda like Markdown”. When you are trying to author large sets of documents, it isn’t the correct tool.[17]
Why You Shouldn’t Use “Markdown” for Documentation
Build Process
I use Cloudflare Pages to build and deploy this website. Like most platforms for static websites, the Page is connected to GitHub. On pushing changes to the repository, Cloudflare Pages automatically builds and deployes the website. Changes to non-main branches are deployed to a preview URL.[23]
With the GitHub integration, Cloudflare Pages lets you configure a short build command like npm run build
that it executes for every build. It supports various technologies including Node.js, Python, Ruby, and Java 8.[24]
To generate documentation with every build, you would have to include this in the short build command. Potentially, the build command could execute a shell script. The documentation of the build configuration does not mention support for executing docker containers.
As an alternative to the git integration, Cloudflare Pages offers a Direct Upload capability. You can build the static website using any build setup, and then upload the static files to Cloudflare Pages. This gives you full flexibility for the build pipeline and allows you to use more elaborate CI/CD processes – like including a step to generate documentation.[25]
GitHub Actions [26] is GitHub’s integrated CI/CD platform. GitHub offer 2,000 CI/CD minutes per month for free for public repositories[27]. Actions allows you to run docker containers within a workflow – for exampe to render diagrams. Cloudflare Pages provide a GitHub Action for their Direct Upload feature[28].
Goals and Principles
My top quality goals for this website are Performance Efficiency, Reliability, and Portability. One of my principles is to treat this website as a playground for learning.[29]
4.4.3. Decision
I will implement documentation as code.
I will use AsciiDoc and Structurizr for the documentation.
I will use GitHub Actions to build and deploy the website (including documentation) to Cloudflare Pages via Direct Upload.
4.4.4. Consequences
Using documentation as code, I can maintain the documentation together with the code and blog posts – versioned and using the same editor for everything. I can make the documentation available as content of the website.
The change to documentation as code with a CI/CD process changes the deployment process significantly. This could affect portability. On the one hand, it improves portability: the static files are built independent from Cloudflare and could be hosted anywhere on the internet. On the other hand, competing platforms for hosting static websites may not offer a comparable direct upload capability. So the documentation may not be easy to port to another platform, but the rest of the website could be easily built using Netfliy, Vercel, and others.
Following the principle to use the blog as playground for learning, this decision will allow me to gain some experience with AsciiDoc and GitHub Actions.