要在部署期间显示维护页面,我总是在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
。
答案 0 :(得分:11)
对不起,Frank Farmer,但这不起作用。
什么有效但不那么整洁:
请求如何工作 - >
我使用规则#1
if (-f /home/shared/system/maintenance.html) {
return 503;
}
此规则支持指定位置location @maintenance
,并且/maintenance.html
处root /home/shared/errors
的公共重定向一切正常。
此页面包含图片some.jpg
- 要接收此图片,浏览器会启动新请求,此新请求会再次触及规则#1
所有这些都在初始问题中描述但
如果我在Frank Farmer的回答中使用了一些if
魔法,我可以将服务器指向请求的文件但是HTTP回答将是503并且浏览器(所有,除了Safari,在我的测试中)在调试控制台中抛出错误并且做显示图像但不处理相同情况下的CSS文件。
这很关键。
我尝试使用location magic来解决这个问题 - 这意味着我必须:
请勿return 503
查看内容请求并完全跳过指定位置。
请更改root /home/shared/errors
,因为维护内容仍然存在。
最后,我有下一个解决方案:
为所有静态内容创建maintenance-static
文件夹,并在我的maintenance.html
文件和维护静态样式表中更改路径
接下来使用这些规则(我认为它们是自我描述的)在初始问题中替换单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重定向所有文件的相同规则。
答案 1 :(得分:10)
我花了两个小时寻找这个问题的答案,最后找到了这篇文章。似乎它应该更常见。我的解决方案介于Frank's和Wile之间。正如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;
}
像魅力一样工作。 :)
答案 2 :(得分:4)
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;
}
}
答案 3 :(得分: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;
}
}
答案 4 :(得分: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目录中。
答案 5 :(得分:1)
我尝试了上述所有建议,遗憾的是他们没有按预期工作。对我有用的唯一解决方案如下:
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;
}
我知道,它会在正常情况下创建不必要/维护位置,但您可以想象另一个位置路径,您的用户永远不会猜到:)。