BareProxy Maintenance and Failover Pages Plugin: A Static Page When the Backend Is Down
Status: built, number 1 of 21 in BareProxy’s build order, and out in BareProxy 0.4.0 as maintenance.wasm on the releases page. The plugins are built easiest first, and this one was the quickest: one callback on the way in, one on the way out. Its manual is the README in the code repository.
When an app goes down, visitors get whatever the proxy says by default: a bare “502 Bad Gateway” or “503 Service Unavailable”. That reads like the site is broken, because it is. A page that says “we’re doing maintenance, back at 14:00” with the site’s own look reads like a site that’s being looked after.
What It Does
- A failover page. When the backend answers 502, 503 or 504, or BareProxy answers it because no backend is up, the plugin swaps in the site’s own page. The status stays as it was, so search engines know it’s temporary.
- A maintenance switch.
maintenance onin the plugin’s config sends every visitor the maintenance page, with 503, except addresses on an allow list, so the team can still check the site before opening it again. Turning it on or off is a config change like any other:planshows it,applymakes it live,rollbackundoes it. - Retry-After. Both pages tell browsers and crawlers when to come back, five minutes by default.
- Paths left alone. An API whose clients want its own error bodies, or a health check, can be skipped.
- No cached outage. The pages go out with
Cache-Control: no-store, so no cache keeps serving them once the site is back.
Here is a config:
plugin down /etc/bareproxy/plugins/maintenance.wasm
config /etc/bareproxy/plugins/down.conf
site example.com
use down
route /* -> app
And the plugin’s own config, in the same plain style as BareProxy’s:
# down.conf
maintenance off
allow 203.0.113.0/24
retry-after 10m
skip /api/
page
<!doctype html>
<title>Back soon</title>
<h1>Back soon</h1>
<p>We're fixing something. Try again in a few minutes.</p>
end
With no config at all, it sends a plain “Back soon” page for 502, 503 and 504.
Why It Came First
It needs exactly two moments in a request’s life. Before routing, it answers with the maintenance page when maintenance is on. On the response headers, it looks at the status and either lets the response go or replaces it. No outgoing calls, no store, no bodies to read. That made it the right first plugin: it proved the whole path from Rust code in plugins/ to a .wasm file attached to a release, with very little that could go wrong in between.
Its tests run it inside a real BareProxy against a backend that fails with each status, against no backend at all, and in maintenance mode with and without an allow list. A config the plugin can’t read is caught by check, which names the line, before anything goes live.
why on a replaced response shows both sides: what the backend said, and that the plugin answered instead.
The whole program is on the plugins page.