Создание резервной страницы ошибки для nginx, когда корневая директория не существует

Вопрос или проблема

Я настроил конфигурацию для любого домена на моем сервере nginx, чтобы уменьшить объем работы при открытии нового сайта/домена. Эта конфигурация позволяет мне просто создать папку в /usr/share/nginx/sites/ с именем домена/поддомена, и тогда все просто работает.™

server {
    # Перенаправление всех доменов, начинающихся с "www.", на не "www." домены.
    listen 80;
    server_name ~^www\.(.*)$;
    return 301 $scheme://$1$request_uri;
}

server {
    # Перенаправление всех доменов, не начинающихся с "www."
    listen 80;
    server_name ~^(?!www\.).+;
    client_max_body_size 20M;

    # Отправка всех запросов на соответствующий хост
    root /usr/share/nginx/sites/$host;

    index index.html index.htm index.php;
    location / { 
        try_files $uri $uri/ =404;
    }

    recursive_error_pages on;
    error_page 400 /errorpages/error.php?e=400&u=$uri&h=$host&s=$scheme;
    error_page 401 /errorpages/error.php?e=401&u=$uri&h=$host&s=$scheme;
    error_page 403 /errorpages/error.php?e=403&u=$uri&h=$host&s=$scheme;
    error_page 404 /errorpages/error.php?e=404&u=$uri&h=$host&s=$scheme;
    error_page 418 /errorpages/error.php?e=418&u=$uri&h=$host&s=$scheme;
    error_page 500 /errorpages/error.php?e=500&u=$uri&h=$host&s=$scheme;
    error_page 501 /errorpages/error.php?e=501&u=$uri&h=$host&s=$scheme;
    error_page 503 /errorpages/error.php?e=503&u=$uri&h=$host&s=$scheme;
    error_page 504 /errorpages/error.php?e=504&u=$uri&h=$host&s=$scheme;

    location ~ \.(php|html) {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_intercept_errors on;
    }
}

Тем не менее, есть одна проблема, которую я хотел бы решить: когда домен, не имеющий папки в директории sites, используется, nginx выдает внутреннюю страницу ошибки 500, так как не может перенаправить на /errorpages/error.php, поскольку он не существует.

Как я могу создать резервную страницу ошибки, которая будет обрабатывать такие неудачные запросы?

Ниже приведенный код должен решить вашу проблему

  http {
      server {
          error_page 404 http://www.mywebsite.com/error.php;
          error_page 500 http://www.mywebsite.com/error.php;

    }
  ................
  ................
    } 

Возможно, это сработает:
(вместо return 404 в последней секции location вы можете попробовать указать точный URL ошибки)

location / { 
        try_files $uri $uri/ @notfound;
    }

location @notfound {
  root /usr/share/nginx/sites/errorpages;
  return 404;
}

Мне, возможно, нужно подумать об этом больше, но что, если вы попробуете что-то вроде:

location /errorpages {
try_files $uri $uri/  @fallback
}

location @fallback {
root /usr/share/nginx/sites/default
... директивы страницы ошибки ...

}

Где default содержит страницы ошибок для несуществующих сайтов.

По сути, попытайтесь создать условный root.

См.: http://end.re/2011/05/02/nginx-alternative-root-with-conditional-autoindex/

Обновление

Это сработало для случая 404:

location / 
try_files $uri $uri/ @errors;
...
}

location @errors {
try_files $uri $uri/ =510;
root /usr/share/nginx/sites/errors;
error_page 404 = /404.html
}

(Конечно, вам нужно создать файла errors/404.html)

Резервные страницы ошибок в nginx работают следующим образом:

error_page 400 /400.html;
location = /400.html {
    try_files /400.html @error;    # <-- это ваша недостающая часть 1
    internal;                      # рекомендуется
}
location @error {   # <-- это ваша недостающая часть 2
    root /var/www/error;
}

Попробуйте использовать условие if на вашем сервере, которое обрабатывает случаи, когда данного сайта не существует

server {
    # Перехват всех доменов, не начинающихся с "www."
    listen 80;
    server_name ~^(?!www\.).+;
    client_max_body_size 20M;

    # Отправка всех запросов на соответствующий хост

    if(!-d /usr/share/nginx/sites/$host){ 
        set $host notexist
    }

    root /usr/share/nginx/sites/$host;

    index index.html index.htm index.php;
    location / { 
        try_files $uri $uri/ =404;
    ...

И добавьте index.html в /usr/share/nginx/sites/notexist, описывающий, что сайт не существует

Ответ или решение

Создание резервной страницы ошибки для Nginx в случае отсутствия корневого каталога представляет собой интересную и распространенную задачу, особенно когда необходимо управлять множеством доменов с минимальными усилиями. Проблема заключается в том, что при запросе к домену, для которого не существует соответствующего каталога, сервер пытается найти страницы ошибок, которые также могут отсутствовать, что приводит к внутренней ошибке сервера (ошибка 500). Давайте рассмотрим возможные пути решения этой задачи, используя различные подходы конфигурации Nginx.

Теория

Когда сервер Nginx получает запрос, он проверяет конфигурационные файлы, чтобы определить, как обработать запрос. В конфигурации, где каждая папка представляет собой отдельный домен, работа сервера заключается в том, чтобы подсказать, куда направить каждый запрос. Если для домена нет соответствующей папки, логично вернуть пользователю понятное сообщение об ошибке, а не внутреннюю ошибку сервера.

Пример

Рассмотрим вашу текущую конфигурацию Nginx. Вы используете конструкцию, которая пытается установить корневой каталог для каждого пришедшего запроса в соответствии с именем хоста:

server {
    listen 80;
    server_name ~^(?!www\.).+;

    root /usr/share/nginx/sites/$host;
    index index.html index.htm index.php;

    location / { 
        try_files $uri $uri/ =404;
    }

    recursive_error_pages on;
    error_page 404 /errorpages/error.php?e=404&u=$uri&h=$host&s=$scheme;
}

Предположим, что вы хотите улучшить обработку отсутствующих каталогов, когда запрос направляется на несуществующий домен. Это можно сделать путем проверки существования каталога и перенаправления на резервную страницу.

Применение

  1. Условная проверка на существование каталога:

    Вы можите использовать директиву if для проверки существования каталога перед тем, как Nginx попытается обработать запрос:

    if (!-d /usr/share/nginx/sites/$host) {
        return 404;
    }

    Однако стабильнее и безопаснее будет использовать более гибкие методы, такие как соответствующие location блоки, которые более предсказуемы в Nginx.

  2. Определение резервного каталога и страницы:

    Создайте каталог, в котором будет находиться страница ошибки по умолчанию. Например, /usr/share/nginx/sites/default, и создайте там страницу (index.html), информирующую о том, что сайт не существует.

  3. Конфигурация точек возврата и директив errors:

    Создайте отдельный блок location, который будет обрабатывать такие случаи. Это включит условную настройку и специализацию для отсутствующих доменов:

    location @missing {
        root /usr/share/nginx/sites/default;
        try_files /404.html =404;
    }

    Добавьте этот блок в вашу конфигурацию сервера:

    location / { 
        try_files $uri $uri/ @missing;
    }
  4. Обработка неправильных запросов:

    Убедитесь, что любые другие обращения к несуществующим файлам или внутренние ошибки перенаправляются или обрабатываются корректно.

    error_page 404 = /404_fallback.html;
    location = /404_fallback.html {
        root /usr/share/nginx/sites/default;
        internal;
    }
  5. Тестирование и проверка:

    После внесения изменений в конфигурацию сервера перезапустите Nginx и проведите тестирование, чтобы убедиться, что любые запросы к несуществующим доменам обрабатываются без внутренней ошибки 500.

Заключение

Таким образом, ключевыми аспектами этой задачи являются эффективная маршрутизация запросов и предоставление информативной страницы пользователям в случае отсутствия необходимого контента. Правильные директивы и структурированные правила маршрутизации помогут избежать общих проблем и улучшат пользовательский опыт. Эти рекомендации помогут вам создать стабильную и предсказуемую среду для работы с множеством доменов на одном сервере Nginx.

Оцените материал
Добавить комментарий

Капча загружается...