1

I have an nginx proxy in front of my webapp. I want to update the app from time to time and during the update I want the users to see a static page that informs them that the app is having a downtime. No problem until this point.

Now I also want to test the app with a UI test framework, that would require accessing the application during downtime. Note: I cannot afford a test server setup right now.

I have a virtual machine that runs the UI tests, so I would like to modify the nginx config, so only that VM can access the website, all the other IP-s are served a static page.

My basic approach would be to to use an if statement inside the server block that says, if $remote_addr is not , then serve static files with try_files. Otherwise (in case of VM) all traffic goes the same way.

I have tried different solutions, but the simple ones just cannot be implemented like putting the try_files directive inside the if statement.

I also tried rewriting the url, if it is coming from other IPs than the VM, but that means all the css and jpg requests get rewritten as well. So I ended up with something like this:

location ~* ^.+\.(jpg||png|css)$ 
{
    try_files $uri = 404;
}

if ( $remote_addr !~* <VM IP> ) {
  rewrite ^ https://example.com/static.html; 
}  

location /static.html
{
    try_files $uri /static.html = 404;
}
location /
{
# headers
proxy_pass <internal-server>; 
} 

This is a HACK IMO, and actually it doesn't even work. I'm looking for a different and simpler solution from someone who has done something like this before.

I know about the nginx geo module, but I don't think I really need that, also want to keep things simple.

So again, the basic problem is redirecting all traffic to a static page if the IP is not one specified. (the requests urls can be same, so location based solutions doesn't work out for me)

  • Does this server normally proxy everything? So only the maintenance page and its resources should be static? – Richard Smith Oct 10 at 10:53
  • Yes, thats's right! So no modifications should be done on the proxy config, only the static page. – hotigeftas Oct 11 at 10:27
0

You could simplify the configuration by placing all of the static content under a common URI prefix (e.g. /maintenance/...).

For example:

location / {
    if ($remote_addr != '1.2.3.4') {
        rewrite ^ /maintenance/ last;
    }
    ...
    proxy_pass ...;
}
location /maintenance/ {
    root /path/to/root;
    index index.html;
}

The maintenance page is located at /path/to/root/maintenance/index.html. The resource files are located within the same directory and accessed using relative URIs (e.g. foo.css) or with a prefix (e.g. /maintenance/foo.css).

  • Oh my, I was looking for this solution. I tried it out, and it works, but it doesn't actually rewrite the URL that can be seen in the browser nor the URLs in the Network tab. Is this how it should be? I'm quite new to nginx. – hotigeftas Oct 11 at 13:06
  • My example does not redirect as I thought you would not want the browser to potentially cache the maintenance page. If you use rewrite ^ /maintenance/ redirect;, you will get a temporary redirection, but you should also add expires -1; to the maintenance location to disable caching. – Richard Smith Oct 11 at 13:15
  • Oh I see. Very helpful. Btw I could not get it working with the way you provided. Maybe I have not tried it right, but eg. I modified the regex in the rewrite line to rewrite ^(/.*)$ /maintenance$1 last; Maybe it is worth mentioning, that I'm actually one level deeper then I specified, so example.com/pages/index.html. Also I ended up using try_files, because index didn't work for me for some reasons. I'm not saying what you have there is wrong, I just gave up, and stick to a solution that worked. – hotigeftas Oct 11 at 13:24
  • Nevermind, index works as well, I just messed up the syntax! – hotigeftas Oct 11 at 13:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.