≡

wincent.dev

  • Products
  • Blog
  • Wiki
  • Issues
You are viewing an historical archive of past issues. Please report new issues to the appropriate project issue tracker on GitHub.
Home » Issues » Bug #1377

Bug #1377: nginx returns 502 "bad gateway" rather than showing maintenance page

Kind bug
Product wincent.dev
When 2009-09-01T08:12:31Z
Status closed
Reporter Greg Hurrell
Tags no tags

Description

I have a mongrel cluster running behind nginx, and have the latter configured to serve up a maintenance page whenever the site is closed:

   # show maintenance page (added by Capistrano) if present
   if (-f $document_root/system/maintenance.html) {
     rewrite ^(.*)$ /system/maintenance.html last;
     break;
   }

Not sure if this is a new behaviour with the nginx 0.7.x series, but if the mongrel cluster isn't running nginx will return a 502 ("bad gateway") error for all requests rather than showing the maintenance page.

Comments

  1. Greg Hurrell 2009-09-01T09:36:03Z

    Looks like I'm not the first.

    Suggestion to send HUP to nginx master process doesn't work.

  2. Greg Hurrell 2009-09-01T09:41:28Z

    Related, but not quite the same thing: http://www.ruby-forum.com/topic/176115

  3. Greg Hurrell 2009-09-01T10:02:59Z

    Ok, fixed. Looks like I was overzealous with an earlier optimization:

    commit bd5377c529d3017447c69191497c4a06a9013593
    Author: Greg Hurrell <greg@hurrell.net>
    Date:   Sun Feb 22 19:33:58 2009 -0500
    
        nginx: drop unnecessary "if" and "break" directives
        
        We want to fall through here automatically anyway.
        
        Signed-off-by: Greg Hurrell <greg@hurrell.net>
    
    diff --git a/usr/local/nginx/conf/nginx-staging.conf b/usr/local/nginx/conf/nginx-staging.conf
    index 215043c..2ce0909 100644
    --- a/usr/local/nginx/conf/nginx-staging.conf
    +++ b/usr/local/nginx/conf/nginx-staging.conf
    @@ -138,10 +138,7 @@ http {
           }
     
           # everything else goes to the mongrel cluster
    -      if (!-f $request_filename) {
    -        proxy_pass http://mongrels;
    -        break;
    -      }
    +      proxy_pass http://mongrels;
     
         } # end: location
       } # end: server
    diff --git a/usr/local/nginx/conf/nginx.conf b/usr/local/nginx/conf/nginx.conf
    index b007287..147a174 100644
    --- a/usr/local/nginx/conf/nginx.conf
    +++ b/usr/local/nginx/conf/nginx.conf
    @@ -202,10 +202,7 @@ http {
           }
     
           # everything else goes to the mongrel cluster
    -      if (!-f $request_filename) {
    -        proxy_pass http://mongrels;
    -        break;
    -      }
    +      proxy_pass http://mongrels;
     
         } # end: location
       } # end: server

    Turns out that we really do fall through here, despite the rules higher up in the config file. Final version looks like this:

          # serve static content without hitting Rails
          location ~ ^/(images|javascripts|stylesheets)/ {
            expires 10y;
          }
          if (-f $request_filename) {
            break;
          }
    
          # show maintenance page if present
          if (-f $document_root/system/maintenance.html) {
            rewrite ^(.*)$ /system/maintenance.html last;
            break;
          }
    
          # cached pages
          set $cache_extension '';
          if ($request_method = GET) {
            set $cache_extension '.html';
          }
    
          # the above is a hack because nginx doesn't allow nested or ANDed ifs
          if (-f $request_filename$cache_extension) {
            rewrite (.*) $1.html break;
          }
    
          # everything else goes to the mongrel cluster
          if (!-f $request_filename) {
            proxy_pass http://mongrels;
            break;
          }

    This is a little counterintuitive to me. Need to look up what those break, rewrite and last rules really do.

  4. Greg Hurrell 2009-09-01T10:51:27Z

    My understanding of the docs is thus:

    • the if directive is supplied by the rewrite module itself
    • the places where I have a last following my rewrite rules, followed by a break, I could just have a break instead
    • break in both places (as a separate directive or as part of a rewrite rule) means "really stop processing rewrite rules": this is unlike the normal situation where a rewritten URI while be passed along to subsequent rules, and then fed back into the enclosing location block all over again
    • last stops processing rewrite rules (the rewritten URI doesn't get passed along to subsequent rules) but the URI does get fed back into the location block all over again
    • stuff not protected by an if condition will get executed and acted upon regardless of any preceding last or break directives
  5. Greg Hurrell 2009-09-01T10:56:55Z

    Status changed:

    • From: new
    • To: closed
Add a comment

Comments are now closed for this issue.

  • contact
  • legal

Menu

  • Blog
  • Wiki
  • Issues
  • Snippets