In today’s world of increasingly sophisticated cyber threats and high user expectations for uptime, a robust blog architecture is a necessity. I have implemented a cloud-first approach for my blog hosted on Hetzner VM in Germany, leveraging modern technologies and strategies to ensure speed, security, and disaster recovery.

Services used

  1. Hetzner for cloud VMs – Provides industry standard servers for an unbeatable price/performance.
  2. Ubuntu 24.04
  3. Docker Engine
  4. Apache Web Server
  5. Containers
  6. Cloudflare
  7. External Monitoring: Hetrix Tools.

Hosting Environment

The blog runs on a Hetzner VM in Germany, utilizing Ubuntu 24.04 LTS for a stable and secure operating environment. The core web server is Apache, which runs on a non-default port (84xx), to reduce exposure to common attack vectors. WordPress is installed from the source of wordpress.org to the the custom folder under /var/www/<custom name> with corresponding Apache virtual host configuration

WordPress is paired with a MariaDB database running in a restricted Docker container to ensure isolation and limit the attack surface.

Nginx Proxy Manager is the main Docker container which communicates to users via Cloudflare Proxy. Nginx Proxy Manager handles another layer of TLS Termination so in turn website ensure end to end transit communication which we will explain further.

DNS and Cloudflare Integration

DNS resolution is handled by Cloudflare’s authoritative name servers. Cloudflare serves as a powerful edge router, offering a range of security and performance benefits. The Hetzner VM is only whitelisted to accept traffic from Cloudflare’s IP CIDR on port 443, ensuring that all incoming traffic is routed through Cloudflare’s security infrastructure. This setup mitigates direct access to the server, providing an additional layer of protection against DDoS attacks.

Cloudflare WAF (Web Application Firewall) rules are set in place following the standard OWASP recommendations and some custom rules which further filters the traffic.

Cloudflare is configured to cache the content, ensuring that static assets and web pages are delivered quickly to users, even if there is a temporary issue with the origin server. In the event of server downtime, Cloudflare serves the last cached version of the website, keeping it responsive to users who hit the Fully Qualified Domain Name (FQDN).

Web Server and Proxy Setup

The VM (Virtual Machine) or VPS (Virtual Private Service) is running two web servers i.e Apache running on host system and Nginx Proxy Manager on a docker. The default port of Apache is changed to a custom port and the HTTPS port 443 is port forwarded to be served to and from the Nginx Proxy Manager docker container. Let us refer the diagram below for a better understanding.

From the diagram it seems that there are two reverse proxies involved in this connection while visiting this website/blog. When you/user enters the url blog.pathak.biz it is resolved to Cloudflare’s edge. This is the POP (Point of Presence) the user is actually interacting with. From Cloudflare’s edge now the query traverse via the CF (Cloudflare) network which involves the CF WAF and Cloudflare’s exit Edge near the Host i.e Germany.

So, as of now its User > CF Edge > CF WAF > CF Host VM Edge. Now from here the query traverses from CF Host Edge to the VM port 443 which is handled by the the Nginx Docker container. The query further traverses to the same VM port 84xx which is the Apache port, post internal WAF and fail2ban.

Cloudflare helps with the caching and to have a POP (Point of Presence) such that it is near every user irrespective the host server being in Germany.

Here’s a PDF of internal ZTNA architecture of previous version. secureServer.V4drawio.pdf

Security

This section will be somewhat censored/redacted to not truly expose everything security wise. As per the diagram above we saw that the traffic traverses via Cloudflare Network. As the blog is running wordpress at its core, the admin page and other important section are covered by Zero Trust Network Architecture (ZTNA) such as blog.pathak.biz/wp-admin. The requests to the following url is again filtered by Cloudflare WAF and internal policies per Single Sign On (SSO).

An internal SSO server is also used in the picture i.e Authentik running separately which we will talk about it later.

Backup Strategy

The blog’s data is protected by a two-fold backup strategy. The first method leverages UpdraftPlus for WordPress, ensuring that critical files, themes, and database backups are regularly created.

The second method employs Kopia, a powerful backup solution that integrates seamlessly with Hetzner’s storage and backs up web files and the Docker container’s volume bind data to Backblaze S3 Object storage. This dual backup setup ensures that if a recovery is needed, both files and databases are available, regardless of where the failure occurs.

Disaster Recovery and High Availability

A Cloudflare Tunnel (Zero Trust Network Access or ZTNA) is used for disaster recovery. The ZTNA server is hosted in my homelab, ensuring that even if the Hetzner VM completely fails, there is a redundant path for services to remain online.

In case of a full server failure, a Python script is triggered. It uses Cloudflare’s API to remove the DNS A record for the blog and activate a forward proxy on a CNAME. This ensures that even if the primary VM is down, users can still access the site through a secondary proxy, ensuring maximum uptime.

Uptime Monitoring

All the internal services and external endpoints are monitoring using Uptime-Kuma and Hetrix tools for public endpoint. Uptime-Kuma is explicitly used for internal services such as Python script, DNS Check, SQL server, Apache server, nginx server, HomeLAB uptime and Hetrix is particularly used for Public Uptime.

Conclusion

Yes, The above architecture might be somewhat a overkill as this is a hobby blog but being a self-hosted enthusiast individual it is fun to learn and actually apply this in practicality. This architecture ensures that my blog is secure, fast, and resilient to failures. By leveraging Cloudflare for DNS management, caching, and security, alongside Docker for isolated services and a two-tier backup strategy, my setup remains robust and adaptable. Whether it’s ensuring zero downtime or handling unexpected outages, this architecture gives me confidence that my blog will remain available and reliable for users across the globe.

Leave a Reply

Your email address will not be published. Required fields are marked *