Traefik: Custom Error Pages and Returning 503 for Unknown Services
I've been wanting to customize the rather boring default "404 page not found" message that Traefik returns when a service is unknown/unavailable. Occasionally this error is returned when restarting the container running the service or if the container fails to start.
If you have customers visiting some of these services (like I do), then providing some more information on what to do is better than a short and cryptic error message.
5xx
class, except for the 500
, 501
, 503
, and 505
codes.For services that aren't running, the 503 status code is the most optimal, as search engines will see this as a temporary situation and won't impact your site ranking.
In your docker-compose.yaml
file, define a new container that will handle catchall requests and error pages. In this example, I've chosen to re-write the path to /
for catchall requests (the actual request URI path isn't important).
services:
nginx-catch-all:
image: nginx:stable
volumes:
- "./catchall/nginx.conf:/etc/nginx/conf.d/default.conf:ro"
- "./catchall/pages:/usr/share/nginx/html:ro"
labels:
traefik.enable: "true"
traefik.http.routers.catch-all.service: "catch-all@docker"
traefik.http.routers.catch-all.rule: "PathPrefix(`/`)"
# The priority must be lower than all other services
traefik.http.routers.catch-all.priority: 1
traefik.http.routers.catch-all.entrypoints: "https"
traefik.http.routers.catch-all.middlewares: "catch-all"
traefik.http.services.catch-all.loadbalancer.server.port: 80
traefik.http.middlewares.catch-all.replacepath.path: "/"
# This middleware can be applied to other services to return custom error pages, instead of the default/generic pages
traefik.http.middlewares.error-pages.errors.status: "405,406,408,410,429,451,500-599"
traefik.http.middlewares.error-pages.errors.service: "catch-all"
traefik.http.middlewares.error-pages.errors.query: "/{status}.html"
docker-compose.yaml
In the nginx.conf
file, we'll setup a basic server that simply returns static html files (you could also serve dynamically generated pages using e.g.: SSI, PHP, Python).
In the location = /
block that will be used for the catchall requests, we define a custom error page for the 503
status code and return a 503 Service Unavailable error that Traefik proxies to the user.
server {
listen 80;
server_name _;
error_log stderr warn;
access_log /dev/stdout main;
error_page 404 /404.html;
location / {
root /usr/share/nginx/html;
internal;
}
# Catchall requests will be made to the root, return a 503 status code instead.
location = / {
error_page 503 /catchall.html;
return 503;
}
}
With this configuration, all that is left is to create custom error pages that match the status code, e.g. 404.html
and place them in the ./catchall/pages
directory.
Now, when you visit the URL of a service that hasn't fully started yet, your custom "catchall" error page will be displayed with a 503
status code.