Search code examples
dockerdocker-composeserverurl-routingtraefik

How to customize Traefik error pages on docker-compose?


Here is my case, I have an environment of let's say 2 docker containers:

  • Javascript application
  • Traefik

While JS app is building, container is "not available yet". So traefik will display a 502 bad gateway or a 404 not found standard page.

Is there a way to cutomize those pages? In order to display a more user-friendly page?

I've dug the traefik documentation, but without success


Solution

  • Traefik provides error pages middleware

    https://doc.traefik.io/traefik/middlewares/http/errorpages/

    Error pages should be served by another traefik service

    This is defined by using the following labels on the error handling container

    # Dynamic Custom Error Page for 5XX Status Code
    labels:
      - "traefik.http.middlewares.test-errors.errors.status=500-599"
      - "traefik.http.middlewares.test-errors.errors.service=serviceError"
      - "traefik.http.middlewares.test-errors.errors.query=/{status}.html"
    

    and define which middleware will use on the app container:

    labels:
    - "traefik.http.routers.backend-router.middlewares=test-errors-middleware@docker"
    

    This is a basic example that might help you to achieve what you want

    docker-compose.yaml

    services:
      errors:
        image: nginx:alpine
        volumes:
          - ./errors.conf:/etc/nginx/conf.d/errors.conf
          - ./500.html:/usr/share/nginx/html/500.html
        labels:
          - "traefik.enable=true"
          - "traefik.http.services.errors-service.loadbalancer.server.port=80"
          - "traefik.http.routers.errors-router.rule=Host(`error.localhost`)"
          - "traefik.http.routers.errors-router.entryPoints=web"
          - "traefik.http.middlewares.errors-middleware.errors.status=500"
          - "traefik.http.middlewares.errors-middleware.errors.service=errors-service"
          - "traefik.http.middlewares.errors-middleware.errors.query=/{status}.html"
    
      backend:
        image: nginx:alpine
        volumes:
          - ./backend.conf:/etc/nginx/conf.d/backend.conf
        labels:
          - "traefik.enable=true"
          - "traefik.http.services.backend-service.loadbalancer.server.port=80"
          - "traefik.http.routers.backend-router.rule=Host(`test.localhost`)"
          - "traefik.http.routers.backend-router.entryPoints=web"
          - "traefik.http.routers.backend-router.middlewares=errors-middleware@docker"
    
      traefik:
        image: traefik:2.4
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        ports:
          - 80:80
        command:
          - --accessLog=true
          - --api=true
          - --log.level=DEBUG
          - --entrypoints.web.address=:80
          - --providers.docker=true
          - --providers.docker.exposedByDefault=false
          - --providers.docker.network=default
        labels:
          - "traefik.enable=true"
          - "traefik.http.services.traefik-service.loadBalancer.server.port=8080"
          - "traefik.http.routers.traefik-router.rule=Host(`traefik.localhost`)"
          - "traefik.http.routers.traefik-router.entryPoints=web"
          - "traefik.http.routers.traefik-router.service=api@internal"
    

    errors.conf

    server {
      listen 80 default_server;
    
      root /usr/share/nginx/html;
    
      location / {
        try_files $uri =500;
      }
    }
    

    backend.conf

    server {
      listen 80 default_server;
    
      root /usr/share/nginx/html;
    
      location / {
        return 500;
      }
    }
    

    500.html

    <h1>This is broken - HTTP 500 SERVER ERROR</h1>