Skip to content

Commit 189fad4

Browse files
feat(haproxy): add custom 503 maintenance landing page (#1464)
* feat(haproxy): add custom 503 maintenance landing page Add a branded HAProxy error page for 503 responses with: - Inline SVG illustration (server rack scene with floating papers, smoke, and animated sparks/LEDs) - Contact information and provider details - Self-contained HTML+CSS (no external dependencies) Fix HAProxy errorfile format requirements: - Use HTTP/1.1 status line (required by HAProxy 2.7+) - Include Content-Length header matching exact body size - Use CRLF line endings throughout (RFC 7230) - Keep body under HAProxy's 16KB error file limit * Add file size constraint to docs --------- Co-authored-by: Sven Fillinger <sven.fillinger@qbic.uni-tuebingen.de>
1 parent 894f7f2 commit 189fad4

3 files changed

Lines changed: 653 additions & 0 deletions

File tree

haproxy/README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# HAProxy Custom Error Pages
2+
3+
Custom maintenance / error landing pages for the QBiC Data Manager HAProxy setup.
4+
5+
These pages follow the [HAProxy `errorfile` format](https://www.haproxy.com/documentation/haproxy-configuration-tutorials/alerts-and-monitoring/error-pages/):
6+
each file has a `.http` extension, contains the HTTP status line and required headers at the top,
7+
a blank line separator, and then the full HTML response body.
8+
9+
## Files
10+
11+
| File | HTTP Status | When to Use |
12+
|------|-------------|-------------|
13+
| `errors/503.http` | 503 Service Temporarily Unavailable | Scheduled maintenance or temporary service interruption |
14+
| `errors/maintenance-illustration.svg` || Standalone SVG illustration (not used by HAProxy directly) |
15+
16+
## HAProxy Configuration
17+
18+
Add the error pages to your HAProxy configuration. Place the files on your HAProxy host
19+
(e.g. under `/etc/haproxy/errors/`) and reference them in the `defaults` or `frontend` section:
20+
21+
```haproxy
22+
defaults
23+
# Custom error pages
24+
errorfile 503 /etc/haproxy/errors/503.http
25+
```
26+
27+
To serve the maintenance page for **all** traffic during a maintenance window (regardless of
28+
backend status), combine it with a maintenance backend:
29+
30+
```haproxy
31+
# --- Maintenance mode ---
32+
# Enable by uncommenting the maintenance block and commenting out the normal backend.
33+
34+
# backend maintenance
35+
# errorfile 503 /etc/haproxy/errors/503.http
36+
# server maintenance 127.0.0.1:1 disable
37+
38+
# frontend myapp
39+
# # Maintenance mode: route everything to the maintenance error page
40+
# # use_backend maintenance if TRUE
41+
#
42+
# # Normal mode:
43+
# use_backend app_servers
44+
```
45+
46+
### Multiple Error Codes
47+
48+
You can also serve the same maintenance page for other status codes during an outage:
49+
50+
```haproxy
51+
defaults
52+
errorfile 502 /etc/haproxy/errors/503.http
53+
errorfile 503 /etc/haproxy/errors/503.http
54+
errorfile 504 /etc/haproxy/errors/503.http
55+
```
56+
57+
## Page Contents
58+
59+
The error page includes:
60+
61+
- **Informative message** — explains the situation to visitors in a friendly way
62+
- **SVG illustration** — fully inline, no external image dependencies
63+
- **Contact information** — support email: `support@qbic.zendesk.com`
64+
- **Provider information** — QBiC – Quantitative Biology Center, University of Tübingen
65+
with a link to <https://www.info.qbic.uni-tuebingen.de/>
66+
67+
The page is fully self-contained:
68+
- All CSS is inline (no external stylesheets)
69+
- The SVG illustration is embedded inline (no external image files)
70+
- CSS animations bring the illustration to life
71+
72+
### Visual style
73+
74+
- Warm cream colour palette
75+
- Scene: two colleagues with a tilted server rack, smoke and sparks
76+
- Subtle animations: floating papers, flickering LEDs, rising smoke, blinking sparks
77+
78+
## Customisation
79+
80+
### Changing the contact address
81+
82+
Edit the `mailto:` and display text in the `.contact-card` section of `503.http`.
83+
84+
### Changing the page appearance
85+
86+
All styles are in the `<style>` block inside `503.http`. The colour palette is:
87+
88+
| Token | Value | Usage |
89+
|-------|-------|-------|
90+
| Background | `#fefdf7` | Page background |
91+
| Heading | `#c0392b` | Error title |
92+
| Primary | `#2980b9` | Links |
93+
| Card BG | `#f0f4f8` | Contact info card |
94+
| Server rack | `#2d2d2d` / `#4a4a4a` | Rack gradient |
95+
| LEDs | `#e74c3c` | Red error indicators |
96+
| Sparks | `#f1c40f` / `#e74c3c` | Animated sparkle effects |
97+
98+
### Replacing the illustration
99+
100+
Swap the `<svg>` block inside the `.illustration` div with a different SVG or
101+
replace the inline SVG with an `<img>` tag pointing to a standalone image file.
102+
103+
## Format Requirements (HAProxy)
104+
105+
Key rules from HAProxy's `errorfile` specification:
106+
107+
1. File extension **must** be `.http` (not `.html`)
108+
2. File must start with the HTTP status line: `HTTP/1.1 <code> <reason>`
109+
3. Followed by HTTP headers. For `HTTP/1.1` the following are **mandatory** (the parser rejects files missing them):
110+
- `Content-Length: <bytes>` — must exactly match the body size in bytes; without it HAProxy 2.7+ raises _"unable to parse headers"_ at startup
111+
- `Content-Type: text/html` (or `text/html; charset=utf-8`)
112+
4. All line endings must be **CRLF** (`\r\n`) — HTTP/1.1 requires it per RFC 7230
113+
5. A **blank line** (`\r\n\r\n`) separates headers from the HTML body
114+
6. The HTML body follows after the blank line
115+
7. The entire file is served verbatim as the HTTP response
116+
117+
## File size restriction
118+
HA-Proxy has a max cap for the file size per response for the error messages of 16,800 bytes. Stay below that.
119+
120+
## License
121+
122+
Same as the Data Manager project: AGPL-3.0-or-later.

0 commit comments

Comments
 (0)