In this post I will introduce the architecture of the Engineering blog. As most of you will notice, the blog is powered by WordPress. It’s an on-premise solution that is currently served from two Raspberry Pi 4B computers. The system is exposed to the public internet through a tunnel to a lightweight VPS hosted in Germany.
The architecture of a clustered monolith system
The architecture of the system is best described as a clustered monolith. An nginx server load balances two nodes. In addition, that server is also the reverse proxy for the whole cluster. Finally, the system uses MariaDB to persist all its data and backs it up regularly.
Of course, WordPress also serves static files and needs a place to store it’s PHP code. The admin node writes all changes to the database and file volumes. Rsync syncs all the changes from the admin nodes volume to the secondary node. For example, this ensures that a new plugin install will propagate across the cluster. Finally, a local process backs up the volumes.
Each node runs inside a docker container. The container uses Apache as the web server to expose WordPress. The reverse proxy blocks access to the admin interface from the public internet. This provides an additional layer of security. An attacker needs to be inside the VPN in order to access the admin interface.
One of the bottlenecks in scaling such a system is the SQL database. While MariaDB offers replication mechanisms, they are not easy to configure. In addition, there is a risk of corrupting data when switching a new node to master status. While my site doesn’t have yet have that level of traffic, it’s good to plan ahead.
I have deployed my Raspberry Pi computers to three separate locations. My plan is to have a WordPress instance at each one. Therefore, a local database replica will reduce network latency. Each node will query a local copy of the main database. Reads happen more often that writes in a typical WordPress blog. The only exception are user comments. Finally, the geographically distributed nodes ensure some basic disaster protection.
Two approaches to local database replicas
Here are two approaches to SQL replication for WordPress that I have researched. One often mentioned is GlusterFS. It is a distributed file system that ensures a local synced copy of the database files at every location. Such a solution is an example of master-master replication. GlusterFS takes care of ensuring the consistency of the data in all nodes.
Another approach is to use a WordPress plugin that sends reads and writes to separate databases. In that case, normal master-worker replication is sufficient. Writes happen on the remote master database. Given that the read/write ratio is heavily in favor of reads, performance is not compromised. In such a scenario, the read replicas DNS name would be overridden on each node so that it points to local. If I used a container orchestration system like Kubernetes, it would handle this requirements.
I hope I was able to give the reader a basic overview of the current and planned architecture of this blog. It is a topic I will revisit regularly. My objective is to raise responsiveness and durability while keeping costs low as possible. In combination with the unusual choice of server hardware, it should provide an interesting read. Please leave comments and suggestions below. I look forward to an interesting discussion.
- @ 2023-01-23 12:30