No description
  • HTML 94.9%
  • Makefile 4.8%
  • Dockerfile 0.3%
Find a file
2026-03-23 23:46:58 +08:00
manifests init 2026-03-23 20:10:04 +08:00
pages refractor: 503 error page: update styles, add language and theme toggle functionality, and enhance accessibility features 2026-03-23 20:39:16 +08:00
.gitignore refractor: 503 error page: update styles, add language and theme toggle functionality, and enhance accessibility features 2026-03-23 20:39:16 +08:00
Dockerfile fix: update nginx configuration file paths and restructure server block 2026-03-23 23:46:58 +08:00
Makefile init 2026-03-23 20:10:04 +08:00
nginx.conf fix: update nginx configuration file paths and restructure server block 2026-03-23 23:46:58 +08:00
README.md init 2026-03-23 20:10:04 +08:00
README.zh-cn.md init 2026-03-23 20:10:04 +08:00

Traefik "No Available Server" Custom Error Page

Replace Traefik's default "no available server" response with a beautiful, i18n error page that auto-retries until the service is ready.

Problem

When Traefik believes a pod behind an IngressRoute is not ready (during rollouts, restarts, or readiness probe gaps), it returns a bare 503 Service Unavailable with the message "no available server". This is confusing to end users. This project replaces it with a polished page that:

  • Auto-refreshes every 5 seconds until the service recovers
  • Detects the user's browser language (15 languages supported)
  • Can be applied globally at the Traefik entryPoint level -- no per-route changes needed

Architecture

User Request --> Traefik entryPoint (global middleware)
                   |
                   +-- Pod ready -------> Normal response
                   |
                   +-- "no available server" (502/503)
                         |
                         1. Retry Middleware (4 attempts, exponential backoff)
                         |
                         2. Errors Middleware --> error-pages service
                                                    |
                                                    v
                                           Beautiful i18n page
                                         (auto-retries every 5s)

Prerequisites

  • Kubernetes cluster (minikube, k3s, EKS, GKE, etc.)
  • Traefik v2.x / v3.x with CRD support (IngressRoute, Middleware)
  • kubectl, docker

Quick Start

# 1. Build & push the error-pages image
make build IMAGE_NAME=your-registry/traefik-error-pages
make push  IMAGE_NAME=your-registry/traefik-error-pages

# 2. Update the image in manifests/base/error-pages-deployment.yaml

# 3. Deploy error-pages service + middlewares
make deploy

# 4. Configure Traefik to use the middleware globally (see below)

# 5. Verify
make status

Deployment Guide

1. Build and push the error-pages image

make build IMAGE_NAME=your-registry/traefik-error-pages
make push  IMAGE_NAME=your-registry/traefik-error-pages

Update the image in manifests/base/error-pages-deployment.yaml to match.

To preview the page locally before deploying:

make build
make dev
# Open http://localhost:8080/503.html

2. Deploy error-pages and middlewares

make deploy
make status

This creates the following resources in the traefik namespace:

  • error-pages Deployment (2 replicas) and Service (ClusterIP:8080)
  • retry, custom-errors, error-handling Middlewares
  • A low-priority catchall IngressRoute for the error-pages service

3. Configure Traefik to use the middleware globally

This project only deploys the error-pages service and middlewares. You need to configure your Traefik installation separately to apply them globally.

Add the following to your Traefik startup arguments (via Helm values, static config, or CLI flags):

--entrypoints.web.http.middlewares=traefik-error-handling@kubernetescrd
--entrypoints.websecure.http.middlewares=traefik-error-handling@kubernetescrd

The middleware reference format is {namespace}-{name}@kubernetescrd.

Helm example:

# your-traefik-values.yaml
additionalArguments:
  - "--entrypoints.web.http.middlewares=traefik-error-handling@kubernetescrd"
  - "--entrypoints.websecure.http.middlewares=traefik-error-handling@kubernetescrd"
helm upgrade traefik traefik/traefik -n traefik -f your-traefik-values.yaml

After this, all routes on web and websecure entrypoints will use the error-handling middleware automatically. No need to modify individual IngressRoutes.

4. Test with the example overlay

The example overlay deploys a test app (nginx:alpine) with a plain IngressRoute (no middleware reference needed since it's global):

# Deploy the test app
make deploy-example

# Scale to 0 to simulate "no available server"
kubectl scale deployment test-app -n traefik --replicas=0

# Set up local access (minikube)
echo "127.0.0.1 test-app.local" | sudo tee -a /etc/hosts
kubectl port-forward svc/traefik 9080:80 -n traefik &

# Open in browser -- you should see the custom error page
open http://test-app.local:9080

Scale back up to verify auto-recovery:

kubectl scale deployment test-app -n traefik --replicas=1

The error page auto-refreshes and the user lands on the real nginx welcome page within seconds.

Configuration

Namespace

The default namespace is traefik. To change it:

cd manifests/base && kustomize edit set namespace my-namespace

Also update the middleware reference in your Traefik config to match (format: {namespace}-{name}@kubernetescrd).

Image

Edit manifests/base/error-pages-deployment.yaml directly, or use Kustomize images in an overlay:

images:
  - name: davidliyutong/traefik-error-pages
    newName: ghcr.io/yourorg/traefik-error-pages
    newTag: v1.0.0

Retry behavior

Edit manifests/base/middleware-retry.yaml:

  • attempts -- max retries before giving up (default: 4)
  • initialInterval -- first retry delay (default: 500ms), subsequent retries use exponential backoff

Error page content

Edit pages/503.html and pages/502.html, then rebuild the image. The pages are self-contained HTML with inline CSS/JS -- no build tools needed.

Supported Languages

English, Chinese (Simplified / Traditional), Japanese, Korean, French, German, Spanish, Portuguese, Russian, Italian, Arabic (RTL), Turkish, Vietnamese, Thai

Project Structure

.
├── Dockerfile                            # nginx:alpine serving custom pages
├── nginx.conf                            # nginx config (port 8080, /healthz)
├── pages/
│   ├── 502.html                          # Bad gateway error page
│   └── 503.html                          # Service unavailable error page
├── manifests/
│   ├── base/                             # Core resources
│   │   ├── kustomization.yaml
│   │   ├── error-pages-deployment.yaml   # 2-replica nginx deployment
│   │   ├── error-pages-service.yaml      # ClusterIP on port 8080
│   │   ├── middleware-retry.yaml         # Retry 4x with backoff
│   │   ├── middleware-errors.yaml        # Catch 502-503 -> error-pages
│   │   ├── middleware-chain.yaml         # Chain: retry -> custom-errors
│   │   └── ingressroute-error-pages.yaml # Low-priority catchall
│   └── overlays/
│       └── example/                      # Test overlay
│           ├── kustomization.yaml
│           ├── test-app.yaml             # Test app Deployment + Service
│           └── ingressroute-app.yaml     # Test app IngressRoute
├── Makefile
└── README.md

Make Targets

Target Description
build Build the Docker image
push Push image to registry
dev Run locally for preview (port 8080)
deploy Deploy error-pages + middlewares
undeploy Remove all deployed resources
deploy-example Deploy test app and IngressRoute
undeploy-example Remove example overlay
status Check pods, middlewares, IngressRoutes
logs Tail error-pages pod logs
dry-run Preview rendered manifests

Notes

  • This project deploys only the error-pages service and Traefik middlewares. Traefik itself must be configured separately to use them (see step 3).
  • The error-pages Deployment runs 2 replicas by default for high availability.
  • Manifests use traefik.io/v1alpha1 (Traefik v2/v3). For older Traefik versions, change to traefik.containo.us/v1alpha1.
  • The catchall IngressRoute (priority: 1) ensures the error-pages service itself is always reachable by the errors middleware.

License

MIT