我的 Web 应用程序前面有一个 nginx 代理。我想不时更新应用程序,并在更新期间让用户看到一个静态页面,告知他们应用程序正在停机。到目前为止都没有问题。
现在我还想使用 UI 测试框架测试应用程序,这需要在停机期间访问应用程序。注意:我现在负担不起测试服务器的设置。
我有一个运行 UI 测试的虚拟机,所以我想修改 nginx 配置,这样只有该 VM 可以访问该网站,所有其他 IP 都提供静态页面。
我的基本方法是在服务器块中使用 if 语句,该语句表示,如果$remote_addr
不是,则使用 提供静态文件try_files
。否则(在 VM 的情况下)所有流量都会以相同的方式进行。
我尝试过不同的解决方案,但是简单的解决方案无法实现,比如将try_files
指令放在 if 语句中。
我还尝试过重写 URL(如果它来自 VM 以外的其他 IP),但这意味着所有 css 和 jpg 请求也会被重写。所以我最终得到了如下结果:
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>;
}
在我看来,这是一种黑客行为,实际上根本不起作用。我正在寻找一个不同的、更简单的解决方案,来自之前做过类似事情的人。
我了解 nginxgeo
模块,但我认为我并不真正需要它,也想让事情保持简单。
因此,如果未指定 IP,则基本问题是将所有流量重定向到静态页面。(请求 URL 可以相同,因此基于位置的解决方案对我来说不起作用)
答案1
您可以通过将所有静态内容放在一个通用 URI 前缀(例如/maintenance/...
)下来简化配置。
例如:
location / {
if ($remote_addr != '1.2.3.4') {
rewrite ^ /maintenance/ last;
}
...
proxy_pass ...;
}
location /maintenance/ {
root /path/to/root;
index index.html;
}
维护页面位于/path/to/root/maintenance/index.html
。资源文件位于同一目录中,可使用相对 URI(例如foo.css
)或带前缀(例如/maintenance/foo.css
)进行访问。