Back to articles
Technology Insight

Building a High Availability (HA) Architecture for Headless CMS Strapi on Hetzner VPS with HAProxy

May 29, 2026

Introduction: Why High Availability Matters for Headless CMS

In the modern web development ecosystem, the headless content management system (CMS) has transitioned from an architectural trend to an enterprise standard. Strapi, as a leading open-source headless CMS, powers critical digital experiences across e-commerce platforms, corporate websites, and mobile applications. However, as business reliance on these platforms grows, a single-instance Strapi deployment becomes a dangerous single point of failure (SPOF).

Achieving High Availability (HA) ensures that your content API remains operational, resilient, and responsive, even if an underlying virtual private server (VPS) experiences hardware failure, network degradation, or resource exhaustion. This comprehensive guide details how to architect and deploy a production-ready, fault-tolerant Strapi cluster utilizing three Hetzner Cloud VPS instances, coordinated by an HAProxy load balancer and supported by a centralized database and shared storage solution.

The Core Architecture: Nodes, Layering, and the Three-VPS Cluster

Before writing configuration files, it is vital to understand the topology of a high-availability cluster. A resilient architecture requires a clear separation of concerns across three distinct layers: the routing layer, the application layer, and the data layer.

To achieve absolute redundancy without excessive infrastructure costs, we will distribute our services across three high-performance Hetzner Cloud VPS instances (e.g., CPX21 or CPX31 instances running Ubuntu 24.04 LTS). Our architectural layout will be structured as follows:

  • Node 1 (HAProxy + Strapi App 1): Acts as the primary entry point for traffic while simultaneously hosting the first application worker.
  • Node 2 (Backup HAProxy + Strapi App 2): Acts as a passive load balancer (using Keepalived for IP failover) and hosts the second application worker.
  • Node 3 (Strapi App 3 + Shared Services): Hosts the third application worker and acts as a coordinator for system tasks.

Note: For a true enterprise-grade production environment, the database (PostgreSQL) and the media storage (S3-compatible storage) must live completely outside of these application nodes. We will utilize Hetzner Managed Database Services or a dedicated, replicated database cluster alongside an external cloud storage provider like AWS S3 or MinIO.

Step 1: Setting Up the Shared Infrastructure (Database & Storage)

Because Strapi is inherently stateless when configured correctly, multiple instances can run simultaneously and serve the exact same API requests. However, they must all read from and write to the same single source of truth for both data and asset files.

1. Centralizing the Database

Configure your external PostgreSQL instance to accept connections from the private IP range of your three Hetzner servers. Ensure you initialize the database with proper connection pooling constraints, as three simultaneous Strapi instances will naturally increase the concurrent connection count.

2. Offloading Media Assets

By default, Strapi saves uploaded media files to the local filesystem (./public/uploads). In a multi-node architecture, an image uploaded to Node 1 would be missing if a subsequent user requested it from Node 2. To avoid split-brain content delivery, you must install the official S3 provider plugin:

npm install @strapi/provider-upload-aws-s3 --save

Modify your ./config/plugins.js configuration file to force all nodes to stream uploaded media directly to a centralized bucket, ensuring global asset availability.

Step 2: Deploying and Syncing Strapi Across the Nodes

With the external data layer secured, we proceed to deploy the application layer on all three Hetzner VPS instances. To maintain absolute consistency, we recommend using Docker containers or a standardized Git-based deployment pipeline managed by PM2.

Handling Strapi's Administrative Synchronization

Crucial Rule of High Availability Strapi: Only one instance should run database migrations or handle cron-based background jobs. Running simultaneous migrations on three separate nodes during a deployment can cause severe database schema corruption.

To mitigate this risk, configure your deployment script so that Node 1 executes the build and migration phase (strapi build and strapi deploy), while Node 2 and Node 3 are gracefully reloaded only after Node 1 successfully completes its initialization. Use environment variables to control admin execution:

// On Node 2 and Node 3 env file
STRAPI_DISABLE_AUTO_MIGRATIONS=true
CRON_ENABLED=false

Step 3: Configuring HAProxy for Intelligent Load Balancing

HAProxy (High Availability Proxy) is an industry-standard, high-performance TCP/HTTP load balancer. It will sit in front of our three Strapi nodes, evenly distributing incoming REST and GraphQL API requests while constantly monitoring the health of each instance.

Install HAProxy on your designated routing node via the terminal: sudo apt update && sudo apt install haproxy -y. Once installed, overwrite the default configuration file at /etc/haproxy/haproxy.cfg with the following enterprise pattern:

global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    daemon

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend strapi_front
    bind *:80
    # Redirect all HTTP traffic to HTTPS in production
    # bind *:443 ssl crt /etc/ssl/certs/your_domain.pem
    mode http
    default_backend strapi_backend

backend strapi_backend
    mode http
    balance roundrobin
    option forwardfor
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    
    # Health check path optimized for Strapi
    option httpchk GET /_health
    http-check expect status 200
    
    # Cluster Node Definitions
    server strapi-node-1 10.0.0.11:1337 check inter 2s rise 2 fall 3
    server strapi-node-2 10.0.0.12:1337 check inter 2s rise 2 fall 3
    server strapi-node-3 10.0.0.13:1337 check inter 2s rise 2 fall 3

This configuration utilizes the roundrobin algorithm to split traffic equally across your Hetzner backend servers. Crucially, it leverages Strapi's native /_health endpoint. If an application instance crashes, HAProxy will detect the failure within 6 seconds (3 failed checks separated by 2 seconds) and transparently stop routing traffic to that specific node without the end-user ever noticing an interruption.

Step 4: Securing and Testing the Infrastructure

Before launching your cluster into production, validation and stress testing are essential components of infrastructure signing-off.

1. Simulating a Node Outage

To verify the self-healing and failover capabilities of your new HA cluster, initiate a continuous ping or API request loop against your load balancer URL from your local terminal. While the requests are processing, simulate a catastrophic server crash by stopping the Strapi service on Node 1:

sudo systemctl stop strapi # Or docker stop if containerized

Observe your active traffic loop. You should witness HAProxy intercepting the service drop, redirecting ongoing traffic seamlessly to Node 2 and Node 3. The error rate should remain at exactly 0%.

2. Implementing the Admin Panel Caveat (Sticky Sessions)

If you intend to host the Strapi Administration Panel (/admin) behind the same load balancer rather than offloading it to a static hosting platform like Vercel or Netlify, you may experience session disconnection issues. Because the Strapi admin dashboard relies on local token validation states during certain operations, shifting mid-session from Node 1 to Node 2 can trigger unexpected logouts.

To solve this, you can alter the HAProxy backend configuration to utilize sticky cookies for the admin route, ensuring a single content editor stays pinned to the same backend node during their editing session, while standard API requests remain fully distributed across the entire cluster.

Conclusion: Peace of Mind at Scale

By leveraging three Hetzner VPS instances coupled with HAProxy, you transform a default Strapi installation into a resilient, scalable, enterprise-grade content delivery system. If a server goes down for maintenance, or an unexpected traffic spike overwhelms a single node, your architecture adapts autonomously. The nominal investment in configuration and infrastructure design yields immense returns in application uptime, user satisfaction, and data integrity.

Building a High Availability (HA) Architecture for Headless CMS Strapi on Hetzner VPS with HAProxy | DPTCloud