Learn Traefik - High Availability & Clustering
Episode 26 of 31

Learn Traefik - High Availability & Clustering

This episode covers high availability: running multiple stateless Traefik instances, configuration synchronization via providers, sharing acme.json for Let's Encrypt with locking, load balancing in front of Traefik, and /ping health checks for readiness and liveness probes.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

A single Traefik instance is a single point of failure: it dies, and all domains go down. Episode 26 removes that point with high availability — running two or more Traefik instances that work side by side, stateless, and replace each other.

The good news: Traefik is designed to be stateless. All dynamic configuration comes from providers, so a new instance automatically matches the others without manual synchronization. There is only one main challenge: acme.json, which holds the certificate private keys. This episode dissects the HA architecture, shared storage, and how to place Traefik behind a load balancer.

HA Architecture

Stateless Design

The main principles of Traefik HA:

  • No local state: routing configuration is read from providers (Docker, K8s, file) — not from instance files.
  • Identical: all instances run the same static config and see the same providers.
  • Frontend load balancer: traffic is split across several instances; if one dies, the others keep serving.

Two Traefik instances with Compose:

Two Traefik instances
services:
  traefik-1:
    image: traefik:v3
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - shared-acme:/etc/traefik/acme
    networks:
      - edge
  traefik-2:
    image: traefik:v3
    ports:
      - "81:80"
      - "444:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - shared-acme:/etc/traefik/acme
    networks:
      - edge
 
volumes:
  shared-acme:

Both instances use the same providers and the same shared-acme volume. The second instance sits on ports 81 and 444 to avoid conflicts during testing; in production both are placed behind an external load balancer.

Configuration Synchronization

Providers as the Source of Truth

Because the provider is the only source of dynamic configuration, there is nothing to synchronize manually:

  • Provider-based sync (Docker, K8s): every instance hears the same events from the Docker socket or Kubernetes API.
  • File provider with shared storage: if using the file provider, store dynamic files on shared storage (NFS, network volume) readable by all instances.
  • Result: routers, services, and middlewares are always identical on all instances.

The only exception is Let's Encrypt certificates — stored in acme.json, which must indeed be shared.

Let's Encrypt in HA

Shared acme.json and Locking

All Traefik instances write to the same acme.json. The problem: two instances updating the file at once can overwrite each other. Traefik handles this with file locking — each instance locks the file before writing, so successive transactions are safe:

  • Use shared storage: NFS, volumes, or object storage (S3/R2) mounted by all instances.
  • Make sure locking works: Traefik uses the flock mechanism on the file — shared storage must support file locking (NFS v4 does).
  • Do not share inconsistent storage — for example loading acme.json from three servers at once without synchronization can corrupt the file.

Let's Encrypt also enforces a rate limit per account. With several instances, make sure all instances use the same email in the certificate resolver so there is one account and one shared limit. Leader election is not needed — Traefik handles consecutive renewals through locking.

Load Balancing Traefik

Four Approaches

  • DNS round-robin: several A records for the same name; the browser picks randomly. Simple but does not handle failover.
  • External load balancer: an NLB/ALB in the cloud or HAProxy in front of the Traefik instances.
  • Keepalived/VRRP: a shared virtual IP between hosts; automatic failover at the network level.
  • Cloud load balancers: AWS, GCP, and Azure provide health checks and automatic traffic distribution.

Whatever the frontend, it needs to know when a Traefik instance is healthy — that is where the /ping endpoint comes in.

The /ping Health Check

Readiness and Liveness

Enable ping in static config:

Static config: ping endpoint
ping:
  entryPoint: health

Define a dedicated health entrypoint that must not be publicly exposed:

Health entrypoint
entryPoints:
  health:
    address: ":8082"

Then configure the external load balancer to check instance health:

Testing the ping health check
curl -s http://localhost:8082/ping

A 200 OK response means the instance is healthy and ready to receive traffic; any other status means the load balancer should remove it. The curl command above is the same manual verification tool that health probes use.

Tip

Separate the health entrypoint from public traffic entrypoints. If the health check is open to the internet, attackers can read instance status — informative but unnecessary. Restrict it with a firewall or IPWhiteList.

Closing

Key takeaways:

  • Traefik is stateless: all instances are identical because configuration comes from providers.
  • File provider synchronization uses shared storage.
  • acme.json is shared with locking; use the same account email.
  • Load balancing in front: DNS round-robin, external LB, keepalived, or cloud LB.
  • /ping provides the health signal for health probes.
  • Health checks ensure dead instances leave the rotation automatically.

In episode 27 next we will cover performance tuning — optimizing memory and CPU usage, transport configuration for keep-alive and timeouts, TLS performance with session resumption and HTTP/2, middleware strategy, and benchmarking with wrk, ab, and k6.

Learn Traefik - High Availability & Clustering | Learn Traefik