Nginx custom internal error page when upstream is down
I am new to Nginx and have a reverse proxy to an upstream glassfish server. I am trying to set up a custom 503 page for when the app is down for maintenance. I have been failing to do so for several hours now. The maintenance.html page contains a css and jpg link. These are showing up when I am forwarded to the maintenance page. All I get is the text of the page and a broken image.
CentOS 6.5 nginx 1.4.4 (from nginx repo)
upstream glassfish {
server <upstream IP>:8181 max_fails=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
error_page 404 502 /static/error.html;
error_page 503 /static/maintenance.html;
location ~ ^/static/ {
internal;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass https://glassfish;
port_in_redirect off;
}
}
The error that shows up in the access.log is
[19/Dec/2013:17:49:17 -0500] "GET /static/main.css HTTP/1.1" 404 1136 "http:/// [19/Dec/2013:17:49:18 -0500] "GET /static/header-logo.jpg HTTP/1.1" 404 1136 "http:///
I have checked that /etc/nginx/html/static/header-logo.jpg exists
I'm sure it's simple enough, but I just cannot figure it out!
I recently wanted to do the same thing (show a nicer maintenance/error-page with images, CSS and custom fonts).
What I ended up doing was using an internal location block like this:
server {
…
error_page 502 = @maintenance;
location @maintenance {
root /path/to/maintenance-site;
if (!-f $request_filename) {
rewrite ^ /index.html break;
}
}
}
I wrote a blog post about it, if you need more detail (has been down because I was rebuilding my infrastructure but is back up again).
You say you're doing this:
location ~ ^/static/ { internal; }
The internal
keyword means that this location
is only visible for internal requests, which your error_page
requests are.
If you want to be able to access /static/
directly from the web-browser, which would seem necessary in order to serve images referenced from the error pages, then you'd have to remove the internal
directive from the said location
.
I think the best approach is to do the following things:
- Use
inline CSS
- Convert your images to
Base64
After doing this, you can embed the generated Base64 string into the background-image
CSS rule as follows:
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEADI.....==)
You can use the string with the <img>
tags as well, just pass it to the src
attribute as follows:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEADI.....==" />
This way you can keep the internal
nginx rule.
Cheers!