1

It's much variants described in Internet how to display maintenance page with nginx. But I didn't find the solution to check if user is a developer and not to display maintenance page for developers.

I use try_files, which does't works as I need after any IF-section was entered. So I made my own solution, which I want to share. It works in any configuration with try_files, proxy and so on.

2 Answers 2

1
  1. In http section (out of any server section) check the user if he is a developer:

    map $http_cookie $isDevHack {
        default "";
        ~DEVELOPER_SECRET=1010 "/non-existed-location";
    }
    

    User is a developer if he had DEVELOPER_SECRET with 1010 value in this case. This map is shared for all servers in config.

  2. Append server section with 503-error handler:

    error_page 503 @maintenance;
    location @maintenance {
         rewrite ^(.*)$ /maintenance-mode.html break;
    }
    

    maintenane-mode.html is a page to display for non-developer users in maintenance mode. File path is relative to document_root of current server.

  3. In location sections, which must be protected in maintenance mode, add before any normal-mode rules:

    if (-f "$isDevHack/home/site-home/maintenance") {
        return 503;
    }
    

    If current user is a developer, checked file name will be prepended with /non-existed-location prefix and if will never be entered.

1

I have a fairly simple server setup for which the configuration at the end of the answer will do the following:

  1. If a file named MAINTENANCE exists one level above the root, then the server will be in maintenance mode. (This is the -f test).

  2. Except that if there exist a cookie named foo_dev with the value secret!, the check described above will be bypassed and nginx will serve the data as if the server were not in maintenance mode. (This is the $cookie_foo_dev = "secret!" test.)

I've tried with some try_files settings and did not run into any issue.

Here is the configuration.

server {
    # ... omitted stuff that does not pertain to the solution ...

    root <some path>;

    if ($cookie_foo_dev = "secret!") {
        break;
    }

    if ( -f $document_root/../MAINTENANCE) {
       return 503;
    }

    error_page 503 @maintenance;
    location @maintenance {
        rewrite ^(.*)$ /maintenance.html break;
    }

    location / {
        proxy_pass http://localhost:8000;
    }
}

All incoming connections are required to use HTTPS so the cookie never goes in plain text over the Internet.

I've also set the server to which nginx forwards the requests to display a big fat warning if the cookie foo_dev is set so that I don't mistakenly forget that the site is in maintenance mode.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .