2

I have the following nginx config that handles serving my static website and redirecting requests to my REST backend:

server {
    listen 80 default_server;
    server_name _;

    # Host static content directly
    location / {
        root /var/www/html;
        index index.html;
        try_files $uri $uri/ =404;
    }

    # Forward api requests to REST server
    location /api {
        proxy_pass http://127.0.0.1:8080;
    }

}

If my REST backend goes offline the proxy module returns an HTTP status of "502 Bad Gateway" and I can redirect requests to a status page by adding the following:

# Rewrite "502 Bad Gateway" to "503 Service unavailable"
error_page 502 =503 @status_offline;

# Show offline status page whenever 503 status is returned
error_page 503 @status_offline;
location @status_offline {
    root /var/www/html;
    rewrite ^(.*)$ /status_offline.html break;
}

However, this will only work for requests that access the REST backend directly. How can I redirect requests to my static website in the same way whenever the backend is offline?

Silveri
  • 4,836
  • 3
  • 35
  • 44
  • maybe stop web server? – Artem Ilchenko Dec 07 '18 at 10:03
  • Do you want a solution that works when your backend goes offline for unexpected reasons? Or do you simply want to redirect when you take your site down for maintenance? – nebuler Dec 11 '18 at 22:46
  • @nebuler When it goes down unexpectedly (if not I would use the approach at https://serverfault.com/a/310825/208021). I'll update the question to clarify. – Silveri Dec 12 '18 at 08:02

2 Answers2

4

Nginx does have some health check and status monitoring capabilities that seem like they could be related, but I couldn't find a proper way to use them.

While its intended use case is actually for authorization, I found nginx's auth_request module to work for me:

# Host static content directly
location / {
    # Check if REST server is online before serving site
    auth_request /api/status; # Continues when 2xx HTTP status is returned
    # If not, redirect to offline status page
    error_page 500 =503 @status_offline;

    root /var/www/html;
    index index.html;
    try_files $uri $uri/ =404;
}

It will call /api/status as a subrequest before serving the static content and will only continue when the subrequest returns an HTTP status in the 200 range. It seems to return status 500 when the server is offline.

This method might have some performance implications since you're now always doing an extra request, but that seems to be an inherent requirement of checking whether your service is online.

Silveri
  • 4,836
  • 3
  • 35
  • 44
0

I think this is the correct answer - auth request is ideal for any situation where you want to "ping" a backend before returning the requested content.

I have used a similar scheme in the past for an nginx server where I wanted to check if an auth header was correct before proxying to an S3 bucket.

Elliot Nelson
  • 11,371
  • 3
  • 30
  • 44