nginx;仅使用 try_files 如果文件存在则返回响应代码

2024-04-13

Since IfIsEvil http://wiki.nginx.org/IfIsEvil我一直在尝试使用指令设置配置try_files只是为了让维护页面与响应代码 503 一起显示,对于任何 URI,无一例外,即包括 php 页面(如果存在维护文件)。

我的配置有两个问题:

  1. php URI 不会显示维护页面。
  2. 如果maintenance.html文件存在,则不会返回响应码503。

我见过类似的问题[1] https://stackoverflow.com/q/5600448/1257965,[2] http://forum.nginx.org/read.php?2,226232但没有一个解决方案使用try_files仅(而不是使用if指令),并且如果存在相应的文件,则无条件地使用响应代码 503 提供维护页面。这样的解决方案可能吗?

下面是我当前的非工作conf 文件。它不包含 503 响应代码设置,因为我不明白它应该去哪里才能使其按上述方式工作。

worker_processes            1;

error_log                   /var/log/nginx/error.log debug;

events {
    worker_connections      1024;
}

http {
    include                 mime.types;
    default_type            application/octet-stream;

    index                   index.php index.html index.htm;

    server {
        listen                  80;
        server_name             rpi;
        root                    /www;

        location / {
            try_files           /maintenance.html $uri $uri/ /index.php?$args;

            # pass the PHP scripts to FastCGI server
            location ~ \.php$ {
                try_files           $uri =404;
                fastcgi_pass        unix:/run/php-fpm/php-fpm.sock;
                fastcgi_index       index.php;
                include             fastcgi.conf;
            }
        }
    }
}

我想我的问题也可以这样表述:可以吗?try_files使工作成为if控制结构?如果它本身不能实现上述目标,是否可以与其他指令结合起来发挥作用,排除if指示?

edit:下面是一个解决方案,使用if我目前正在使用它,将其包含在服务器部分中:

error_page              503 @maintenance;

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

location @maintenance {
        try_files       /maintenance.html =404;
}

非常好的问题!但这根本不可能,除非您调用某种设置正确响应代码的脚本。

仅使用 nginx 且无 if 的可行解决方案

The try_files指示 http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files仅对最后一条语句执行内部重定向。但我们可以将它与index指示 http://nginx.org/en/docs/http/ngx_http_index_module.html#index并强制内部重定向。

# This will be the HTML file to display for the 503 error.
error_page 503 /maintenance/maintenance.html;

# Let nginx know that this particular file is only for internal redirects.
location = /maintenance/maintenance.html {
  internal;
}

# Any request that starts with the maintenance folder is 503!
location ^~ /maintenance/ {
  return 503;
}

# Instead of checking if a file exists and directly delivering it we check
# if a certain directory exists and trigger our index directive which will
# perform an internal redirect for us.
location / {
  expires epoch;
  try_files /maintenance/ $uri $uri/ /index.php?$args;
}

这种方法有什么缺点吗?

  • 实际 301 重定向到目录,而不是停留在相同的 URL(搜索引擎)。
  • 301 重定向的浏览器缓存可能是一个问题,这就是我添加expires epoch到位置块。

其他解决方案?

通过nginx配置文件

与其创建 HTML 文件,为什么不创建 nginx 配置文件并简单地重新加载进程呢?

  • 性能好得多!
  • 更容易理解!
  • 无副作用!

nginx 配置可能如下所示(请注意,if一点也不邪恶):

error_page 503 /maintenance.html;

location / {
  include maintenance.conf;
  if ($maintenance = 1) {
    return 503;
  }
  try_files $uri $uri/ /index.php?$args;
}

内容maintenance.conf file:

set $maintenance 0;

如果您想激活维护模式(在您的 shell 中):

echo set $maintenance 1;> maintenance.conf && service nginx reload

给shell朋友更进阶例如,您甚至可以用它扩展初始化脚本我的 LSB 兼容的 https://github.com/Fleshgrinder/nginx-sysvinit-script通过替换文件末尾的以下块:

*)
  echo "Usage: ${NAME} {force-reload|reload|restart|start|status|stop}" >&2
  exit 1
;;

使用以下块:

maintenance)
  echo "set $maintenance 1;" > /etc/nginx/maintenance.conf && service nginx reload;
;;

production)
  echo "set $maintenance 0;" > /etc/nginx/maintenance.conf && service nginx reload;
;;

*)
  echo "Usage: ${NAME} {force-reload|reload|restart|start|status|stop|maintenance|production}" >&2
  exit 1
;;

现在您只需执行以下命令(包括自动完成)即可进入维护模式:

service nginx maintenance

或者执行以下操作以恢复生产:

service nginx production

使用脚本/PHP 文件

另一种极其简单且神奇的方法是使用 PHP 文件来处理它。

location / {
    try_files /maintenance.php $uri $uri/ /index.php?$args;
}

您的 PHP 文件看起来与您的 HTML 文件完全相同,您只需将以下内容添加到它的开头(假设 PHP 5.4+):

<?php http_response_code(503) ?><!doctype html>
<html>
<head>
<!-- ... more html ... -->
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nginx;仅使用 try_files 如果文件存在则返回响应代码 的相关文章

  • Microsoft Edge 不会在 Vagrant VM 中加载本地 nginx 网站

    我遇到了一个奇怪的问题 Microsoft Edge 无法加载托管在 vagrant 虚拟机内的本地 Craft CMS 网站 任何加载本地配置的主机名或 IP 的尝试都会返回 嗯 我们无法访问此页面 错误 我的主机文件中有一行 192 1
  • 使用 apt-get install nginx 后重新编译 nginx

    我最初是通过 apt get install 安装 nginx 的 它工作得很好 现在 我想安装一些第 3 方模块 并且必须重新编译 nginx 所以我尝试重新编译 它只是走过场 然后我意识到我的原始版本仍然是正在使用的版本 我是否需要先卸
  • 在 nginx 重写中发送额外的标头

    现在 我正在将我的应用程序的域从app example com to app newexample com使用以下内容nginx config server server name app example com location app
  • nginx;仅使用 try_files 如果文件存在则返回响应代码

    Since IfIsEvil http wiki nginx org IfIsEvil我一直在尝试使用指令设置配置try files只是为了让维护页面与响应代码 503 一起显示 对于任何 URI 无一例外 即包括 php 页面 如果存在维
  • nginx auth_basic 时间限制

    我正在使用 nginx 和auth basic模块 但我似乎找不到一种方法来指定 身份验证 过期的时间间隔 我希望能够强制 nginx 每 6 小时询问一次密码 有没有办法做到这一点 如果不是 可接受的解决方法是什么 这可能是不可能的 似乎
  • Meteor - 自动发起客户端登录

    我有一个 Meteor 应用程序 我使用 nginx 和内部 SSO 服务进行身份验证 我能够成功地完成此操作 并在服务器 Meteor onConnection 方法上的 nginx 设置 http 标头中检索用户详细信息 此时 我不确定
  • Docker-nginx-反向代理:使用 docker-compose 构建时在上游找不到主机

    我正在使用 NGINX 容器将某些请求重定向到另一个容器 运行 docker compose up d 时 我收到以下错误 2019 09 26 18 05 00 emerg 1 1 在 etc nginx nginx conf 10 中的
  • 如何在 Nginx 中将会话/cookie 从主域传递到子域?

    因此 我的主域中有一个子域的 iframe 页面 并且该子域页面需要用户登录并具有要访问的成员资格 基本上我需要将会话变量和 cookie 传递到子域以便加载 iframe 我怎样才能在 Nginx 中实现这一目标 饼干有一个domain属
  • Laravel 路由使用 nginx 覆盖 phpmyadmin 路径

    我的 LEMP Droplet 上有以下 nginx 配置 server listen 80 default server listen 80 default server ipv6only on root var www html pub
  • X-FRAME-OPTIONS: DENY 通过 nginx 来自 Django 站点在哪里?

    我的 Django 网站使用django summernote https github com summernote django summernote在 iframe 中 并抛出此错误 多个具有冲突值的 X Frame Options
  • 站点启用/中不允许使用 nginx“mail”和“stream”指令

    当我尝试在 nginx 中使用流或邮件指令时遇到问题 我正在使用 nginx 1 16 1 和 Ubuntu 18 04 4 LTS 这是我的 nginx conf user www data worker processes auto p
  • 为从 nginx 反向代理转发的请求添加唯一 id

    我们运行 nginx 作为反向代理 将请求转发到运行 Compojure 的 Clojure 应用程序 Compojure 是一个封装 Jetty 的库 为我们的应用程序提供服务 Web 请求的能力 目前 我们捕获 nginx 和 Cloj
  • Amazon ECS - 在 Docker 入口点上使用 IAM 角色时权限被拒绝

    我正在寻找一种将机密 证书注入 Amazon ECS 容器的方法 就我而言 它是一个简单的 nginx 容器 我一直在使用 AWS Parameter Store 关注这篇文章 https aws amazon com blogs comp
  • 命名 Docker 卷以共享构建而不更新

    我工作的公司的开发人员要求我用 Docker 做一些不同的事情 然后我也被使用了 目标是拥有 2 个具有以下职责的容器 容器A 节点容器将构建前端 React 应用程序并将捆绑包放入名为的目录中app dist 完成后 容器将停止运行 容器
  • 为什么在生产中得到空 CSS 文件?

    我在文件中放入了很多css文件active admin css scss Active Admin s got SASS import active admin mixins import active admin base import
  • Docker 与 nginx 组合不断显示欢迎页面

    我是新来的docker并尝试使用最简单的 docker compose yml 显示一个 hello world 页面 并在此基础上构建最终完整的LEMP堆栈它将与我的服务器具有相同的配置 然而大多数教程已经过时 并且有很多使用方法dock
  • 如何将亚马逊颁发的免费证书配置到nginx.config

    我已经安装了nginx服务器在Amazon Linux 2环境 在创建弹性负载均衡器期间 我创建了 Amazon 的免费证书 现在 我想通过以下方式访问我的服务器https port 443 我该如何配置这个SSL证书在nginx conf
  • 上传大文件(几 GB)时,nginx 返回内部服务器错误

    我在 nginx 后面有一个 Artifactory 上传大于 4 GB 的文件失败 我相当确定这是 nginx 的错误 因为如果文件从本地主机上传 上传到本地主机 则不会出现问题 nginx 设置为client max body size
  • Nginx 正在向 uWSGI 发出非常旧的请求?

    我看到一种奇怪的情况 Nginx 或 uwsgi 似乎正在建立一个很长的传入请求队列 并在客户端连接超时后很长时间内尝试处理它们 我想理解并停止这种行为 以下是更多信息 My Setup 我的服务器使用 Nginx 通过 Unix 文件套接
  • Nginx - 自定义 404 页面

    Nginx PHP 在 fastCGI 上 对我来说非常有用 当我输入不存在的 PHP 文件的路径时 我不会得到默认的 404 错误页面 任何无效的 html 文件都会出现该错误页面 而只会得到 未指定输入文件 如何自定义此 404 错误页

随机推荐