2011-05-12 78 views
16

部署過程中表現出的維護頁面我一直使用下一個配置在nginx的:nginx的維護頁面

if (-f /home/shared/system/maintenance.html) { 
    return 503; 
} 

error_page 503 @maintenance; 

location @maintenance { 
    root /home/shared/errors; 
    rewrite ^(.*)$ /maintenance.html break; 
} 

而且一切正常,直到我需要添加靜態內容維護頁面(圖片,樣式表等)

沒有在error.log中有這樣的記錄靜態內容的工作:

2011/05/05 02:47:20 [notice] 13760#0: *6 "^(.*)$" matches "/some.jpg", client: x.x.x.x, server: server.com, request: "GET /some.jpg HTTP/1.1", host: "server.com" 
2011/05/05 02:47:20 [notice] 13760#0: *6 rewritten data: "/maintenance.html", args: "", client: x.x.x.x, server: server.com, request: "GET /some.jpg 2 HTTP/1.1", host: "server.com" 

這是合乎邏輯 - 如果我做重寫一切maintenance.html這意味着靜態續恩不排除。

但我不能找到任何合適的解決方案,使重定向到每一個文件,除了其在root /home/shared/errors文件夾物理存在的。

PS。 /home/shared/errors不常見的項目文件夾共享任何資源 - 這是完全不同的文件夾中(即使沒有任何符號鏈接/current爲項目

回答

10

。對不起,弗蘭克農民,但這不起作用

什麼工作,但不是那麼整齊。

個如何請求工作 - >

  1. 我使用規則#1

    if (-f /home/shared/system/maintenance.html) { 
        return 503; 
    } 
    

    這個規則有一個支持命名的位置location @maintenance的和共同的重定向到/maintenance.htmlroot /home/shared/errors一切正常。

  2. 此頁面包含與圖像some.jpg - 獲得這個圖像瀏覽器啓動新的要求和新的要求再次命中規則#1

    這一切在最初的問題進行描述,但

    ,如果我使用了一些if魔像弗蘭克農民答案我可以指向服務器請求文件,但HTTP答案將是503和瀏覽器(所有的,除了Safari瀏覽器,在我的測試)拋出的錯誤在調試控制檯和不顯示圖像,但並不處理CSS-文件中同樣的情況。

    這是至關重要的。

  3. 我試圖解決這個使用魔法的位置爲我的新內容的請求 - 這意味着我必須:

    1. 做內容的請求不return 503並跳過所有命名的位置。

    2. 做改變root /home/shared/errors因爲保養內容仍然存在。

  4. 最後,我有一個解決方案:

    1. 創建maintenance-static文件夾中的所有靜態內容,並更改我的maintenance.html文件和維護靜態樣式表的路徑

    2. 下次使用這些規則(我相信它們是自描述性的)在最初的問題中取代單個if (-f /home/shared/system/maintenance.html)

      set $can503 0; 
      if (-f /home/shared/system/maintenance.html) { 
          set $can503 1; 
      } 
      if ($uri ~* /maintenance-static/) { 
          set $can503 0; 
      } 
      location /maintenance-static/ { 
          root /home/shared/errors; 
      } 
      if ($can503 = 1) { 
          return 503; 
      } 
      

此解決方案,而不在所有瀏覽器的任何錯誤,併爲衆多的shared/errors文件夾頁,爲前。 maintenance.html,error.html,overload.html等

這個解決方案不是很清楚 - 可能你可以告訴我如何使它更整潔,但記住我們正在處理單獨的請求(和單獨的nginx進程對於高負載情況下的每個文件/請求等),對於初始html及其內容,我們不能使用503重定向所有文件的相同規則。

3
location @maintenance { 
    root /home/shared/errors; 
    rewrite (some\.jpg|some2\.gif)$ /$1 break; 
    rewrite ^(.*)$ /maintenance.html break; 
} 

這可能不枚舉白名單文件的工作:

location @maintenance { 
    root /home/shared/errors; 
    if (!-f $request_filename) { 
     rewrite ^(.*)$ /maintenance.html break; 
    } 
} 
+0

太棒了!謝謝,但有沒有解決方案不列出每個文件?這不是問題 - 我有很少的文件,但這將是更好的解決方案... – 2011-05-14 05:42:45

+0

@wile看到我的編輯。 – 2011-05-14 19:49:46

+0

@FrankFarmer有趣的是,你的回答會讓我大飽口福,因爲我最終想出了完全相同的代碼(參見我的[博客文章])(http://www.relativkreativ.at/articles/graceful-error -pages-with-nginx)如果你感興趣的話)。 – 2014-06-22 16:04:22

9

我花了兩個小時尋找這個問題的答案,並最終找到了這篇文章。似乎它應該更常見。我的解決方案落在弗蘭克和威爾之間的某處。正如Wile所述,某些瀏覽器(例如Chrome)會選擇不呈現任何返回503的文件的CSS/JS,即使它完全正確地提取它們。

但有一個修復程序比Wile做得少。只需返回200!

我的完整的解決方案如下:

error_page 503 @maintenance; 

location @maintenance { 
    root /path_to_static_root; 
    if (!-f $request_filename) { 
     rewrite ^(.*)$ /rest_of_path/maintenance.html break; 
    } 
    return 200; 
} 

工作就像一個魅力。 :)

+0

謝謝!我也會試試這個,看起來還不錯 – 2012-01-10 11:47:11

+0

你知道如果nginx處理錯誤的方式有任何改變嗎?而不是返回200它現在返回502.它只有502如果文件實際存在(這不包括「maintenance.html」請求) – crockpotveggies 2012-02-18 02:51:45

+0

作出更新,當充當反向代理時確實存在一個全新的問題。這裏的問題http://stackoverflow.com/questions/9338130/nginx-502-when-issuing-error-page-content – crockpotveggies 2012-02-18 06:06:07

1
server { 
    listen 80; 
    server_name myserv.trunk; 
    autoindex off; 
    access_log /var/log/nginx/sitename-access.log; 

    location ^~ /static/ { 
     root /home/dev/myserv-site/; 
    } 

    location ~ /(?P<language>en)?/? { 
     uwsgi_pass unix:///tmp/uwsgi.sock; 
     include uwsgi_params; 
     error_page 502 @fallback; 
     error_page 503 @maintenance; 
     if (-f /home/dev/myserv-site/maintenance.active) { 
      return 503; 
     } 
    } 

    location @fallback { 
     root /home/dev/myserv-site/; 
     if ($language) { 
      rewrite ^(?!\/static\/)(.*)$ /static/html/502.$language.html break; 
     } 
     rewrite ^(?!\/static\/)(.*)$ /static/html/502.zh.html break; 
    } 

    location @maintenance { 
     root /home/dev/myserv-site/; 
     if ($language) { 
      rewrite ^(?!\/static\/)(.*)$ /static/html/503.$language.html; 
     } 
     rewrite ^(?!\/static\/)(.*)$ /static/html/503.zh.html break; 
    } 
} 

以下是可翻譯的維護(503)或502錯誤頁面屏幕的示例。 如果用戶轉到http://site.com/en/英文頁面將會顯示(當存在maintenance.active文件時)。 static dir位於myserv-site目錄內。

2

使用這種解決方案只有一個單一的if語句,並且也更易於閱讀和理解:

upstream unicorn { 
     server unix:/path/to/unicorn.sock; 
} 

server { 
     listen 3000 default deferred; 

     proxy_read_timeout 3600; 
     client_max_body_size 4G; 
     set_real_ip_from 0.0.0.0/0; 

     root /path/to/current/public; 
     try_files $uri/index.html $uri.html $uri @unicorn; 

     error_page 404 /404.html; 
     error_page 500 502 504 /500.html; 
     error_page 503 /system/maintenance.html; 

     location /404.html { 
       internal; 
     } 

     location /500.html { 
       internal; 
     } 

     location @unicorn { 
       if (-f $document_root/system/maintenance.html) { 
         return 503; 
       } 

       proxy_set_header Host $http_host; 
       proxy_set_header X-Real-IP $remote_addr; 
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
       proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; 
       proxy_redirect off; 
       proxy_pass http://unicorn; 
     } 
} 
+0

什麼是'內部'?以及這如何處理維護頁面上的靜態內容?在這裏看不到解決方案 – 2012-05-11 12:40:07

+0

'internal'防止直接訪問位置。有關詳細信息,請參閱http://wiki.nginx.org/HttpCoreModule#internal – unhollow 2012-05-12 19:57:57

+0

靜態資產已正確傳遞,因爲它們甚至不會輸入「@ unicorn」位置。它們由'try_files'處理。 – unhollow 2012-05-12 20:01:00

0

我試過上述建議和不幸預期他們不工作。這只是對我的作品的唯一的解決辦法是:

location/{ 
    if (-f /path/to/file/indicating/maintenance/mode) { 
     rewrite ^(.+)$ /maintenance/$1; 
    } 

    #... the rest of the "normal" logic 
} 

location /maintenance { 
    root /path/where/your/maintenance/root/is; 
    rewrite ^/maintenance/(.*)$ /$1 break; 
    try_files /$uri /index.html =404; 
    return 200; 
} 

我知道,它會在正常條件下,不需要/維護位置,但你能想象另一個位置路徑,你的用戶永遠猜不到:)。