14 KiB
HTTP's error pages
One day you may want to replace the standard error pages of your HTTP server with something more original and pretty. That's what this repository was created for :) It contains:
- Simple error pages generator, written on Go
- Single-page error page templates with different designs (located in the templates directory)
- Fast and lightweight HTTP server (written on Go also, with the FastHTTP under the hood)
- Already generated error pages (sources can be found here, the demonstration is always accessible here)
- Lightweight docker image (~3.5Mb compressed size) with all the things described above
Also, this project can be used for the Traefik error pages customization.
Installing
Download the latest binary file for your os/arch from the releases page or use our docker image:
Registry | Image |
---|---|
Docker Hub | tarampampam/error-pages |
GitHub Container Registry | ghcr.io/tarampampam/error-pages |
Using the
latest
tag for the docker image is highly discouraged because of possible backward-incompatible changes during major upgrades. Please, use tags inX.Y.Z
format
To watch the docker image content you can use the dive:
$ docker run --rm -it \
-v "/var/run/docker.sock:/var/run/docker.sock:ro" \
wagoodman/dive:latest \
tarampampam/error-pages:latest
Dive screenshot
Templates
Name | Preview |
---|---|
ghost |
|
l7-light |
|
l7-dark |
|
shuffle |
|
noise |
|
hacker-terminal |
|
cats |
Note:
noise
template highly uses the CPU, be careful
Usage
All of the examples below will use a docker image with the application, but you can also use a binary. By the way, our docker image uses the unleveled user by default and distroless.
HTTP server
As mentioned above - our application can be run as an HTTP server. It only needs to specify the path to the configuration file (it does not need statically generated error pages). The server uses FastHTTP and stores all necessary data in memory - so it does not use the file system and very fast. Oh yes, the image with the app also contains a configured healthcheck and logs in JSON format :)
For the HTTP server running execute in your terminal:
$ docker run --rm \
-p "8080:8080/tcp" \
-e "TEMPLATE_NAME=random" \
tarampampam/error-pages
And open http://127.0.0.1:8080/404.html
in your favorite browser. Error pages are accessible by the following URLs: http://127.0.0.1:8080/{page_code}.html
.
Environment variable TEMPLATE_NAME
should be used for the theme switching (supported templates are described below).
Cheat: you can use
random
(to use the randomized theme on server start) ori-said-random
(to use the randomized template on each request)
To see the help run the following command:
$ docker run --rm tarampampam/error-pages serve --help
Generator
Create a config file (error-pages.yml
) with the following content:
templates:
- path: ./foo.html # Template name "foo" (same as file name),
# content located in the file "foo.html"
- name: bar # Template name "bar", its content is described below:
content: "Error {{ code }}: {{ message }} ({{ description }})"
pages:
400:
message: Bad Request
description: The server did not understand the request
401:
message: Unauthorized
description: The requested page needs a username and a password
Template file foo.html
:
<html>
<title>{{ code }}</title>
<body>
<h1>{{ message }}: {{ description }}</h1>
</body>
</html>
And run the generator:
$ docker run --rm \
-v "$(pwd):/opt:rw" \
-u "$(id -u):$(id -g)" \
tarampampam/error-pages build --config-file ./error-pages.yml ./out
$ tree
.
├── error-pages.yml
├── foo.html
└── out
├── bar
│ ├── 400.html
│ └── 401.html
└── foo
├── 400.html
└── 401.html
3 directories, 6 files
$ cat ./out/foo/400.html
<html>
<title>400</title>
<body>
<h1>Bad Request: The server did not understand the request</h1>
</body>
</html>
$ cat ./out/bar/400.html
Error 400: Bad Request (The server did not understand the request)
To see the usage help run the following command:
$ docker run --rm tarampampam/error-pages build --help
Static error pages
You may want to use the generated error pages somewhere else, and you can simply extract them from the docker image to your local directory for this purpose:
$ docker create --name error-pages tarampampam/error-pages
$ docker cp error-pages:/opt/html ./out
$ docker rm -f error-pages
$ ls ./out
ghost hacker-terminal index.html l7-dark l7-light noise shuffle
$ tree
.
└── out
├── ghost
│ ├── 400.html
│ ├── ...
│ └── 505.html
├── hacker-terminal
│ ├── 400.html
│ ├── ...
│ └── 505.html
├── index.html
├── l7-dark
│ ├── 400.html
│ ├── ...
...
Or inside another docker image:
FROM alpine:latest
COPY --from=tarampampam/error-pages /opt/html /error-pages
RUN ls -l /error-pages
$ docker build --rm .
...
Step 3/3 : RUN ls -l /error-pages
---> Running in 30095dc344a9
total 12
drwxr-xr-x 2 root root 326 Sep 29 15:44 ghost
drwxr-xr-x 2 root root 326 Sep 29 15:44 hacker-terminal
-rw-r--r-- 1 root root 11241 Sep 29 15:44 index.html
drwxr-xr-x 2 root root 326 Sep 29 15:44 l7-dark
drwxr-xr-x 2 root root 326 Sep 29 15:44 l7-light
drwxr-xr-x 2 root root 326 Sep 29 15:44 noise
drwxr-xr-x 2 root root 326 Sep 29 15:44 shuffle
Custom error pages for your image with nginx
You can build your own docker image with nginx
and our error pages:
# File `nginx.conf`
server {
listen 80;
server_name localhost;
error_page 401 /_error-pages/401.html;
error_page 403 /_error-pages/403.html;
error_page 404 /_error-pages/404.html;
error_page 500 /_error-pages/500.html;
error_page 502 /_error-pages/502.html;
error_page 503 /_error-pages/503.html;
location ^~ /_error-pages/ {
internal;
root /usr/share/nginx/errorpages;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
# File `Dockerfile`
FROM nginx:1.21-alpine
COPY --chown=nginx \
./nginx.conf /etc/nginx/conf.d/default.conf
COPY --chown=nginx \
--from=tarampampam/error-pages:2.0.0 \
/opt/html/ghost /usr/share/nginx/errorpages/_error-pages
$ docker build --tag your-nginx:local -f ./Dockerfile .
More info about
error_page
directive can be found here.
Custom error pages for Traefik
Simple traefik (tested on v2.5.3
) service configuration for usage in docker swarm (change with your needs):
version: '3.8'
services:
error-pages:
image: tarampampam/error-pages:2.0.0
environment:
TEMPLATE_NAME: l7-dark
networks:
- traefik-public
deploy:
placement:
constraints:
- node.role == worker
labels:
traefik.enable: 'true'
traefik.docker.network: traefik-public
# use as "fallback" for any non-registered services (with priority below normal)
traefik.http.routers.error-pages-router.rule: HostRegexp(`{host:.+}`)
traefik.http.routers.error-pages-router.priority: 10
# should say that all of your services work on https
traefik.http.routers.error-pages-router.tls: 'true'
traefik.http.routers.error-pages-router.entrypoints: https
traefik.http.routers.error-pages-router.middlewares: error-pages-middleware@docker
traefik.http.services.error-pages-service.loadbalancer.server.port: 8080
# "errors" middleware settings
traefik.http.middlewares.error-pages-middleware.errors.status: 400-599
traefik.http.middlewares.error-pages-middleware.errors.service: error-pages-service@docker
traefik.http.middlewares.error-pages-middleware.errors.query: /{status}.html
any-another-http-service:
image: nginx:alpine
networks:
- traefik-public
deploy:
placement:
constraints:
- node.role == worker
labels:
traefik.enable: 'true'
traefik.docker.network: traefik-public
traefik.http.routers.another-service.rule: Host(`subdomain.example.com`)
traefik.http.routers.another-service.tls: 'true'
traefik.http.routers.another-service.entrypoints: https
# next line is important
traefik.http.routers.another-service.middlewares: error-pages-middleware@docker
traefik.http.services.another-service.loadbalancer.server.port: 80
networks:
traefik-public:
external: true
Changes log
Changes log can be found here.
Support
If you will find any package errors, please, make an issue in current repository.
License
This is open-sourced software licensed under the MIT License.