Модуль ngx_http_charset_module
Модуль ngx_http_charset_module добавляет указанную кодировку в поле “Content-Type” заголовка ответа. Кроме того, модуль может перекодировать данные из одной кодировки в другую с некоторыми ограничениями:
- перекодирование осуществляется только в одну сторону — от сервера к клиенту,
- перекодироваться могут только однобайтные кодировки
- или однобайтные кодировки в UTF-8 и обратно.
Пример конфигурации
Директивы
Синтаксис: | charset кодировка | off ; |
---|---|
Умолчание: | |
Контекст: | http , server , location , if в location |
Добавляет указанную кодировку в поле “Content-Type” заголовка ответа. Если эта кодировка отличается от указанной в директиве source_charset, то выполняется перекодирование.
Параметр off отменяет добавление кодировки в поле “Content-Type” заголовка ответа.
Кодировка может быть задана с помощью переменной:
В этом случае необходимо, чтобы все возможные значения переменной присутствовали хотя бы один раз в любом месте конфигурации в виде директив charset_map, charset или source_charset. Для кодировок utf-8 , windows-1251 и koi8-r для этого достаточно включить в конфигурацию файлы conf/koi-win , conf/koi-utf и conf/win-utf . Для других кодировок можно просто сделать фиктивную таблицу перекодировки, например:
Кроме того, кодировка может быть задана в поле “X-Accel-Charset” заголовка ответа. Эту возможность можно запретить с помощью директив proxy_ignore_headers, fastcgi_ignore_headers, uwsgi_ignore_headers, scgi_ignore_headers и grpc_ignore_headers.
Синтаксис: | charset_map кодировка1 кодировка2 < . > |
---|---|
Умолчание: | — |
Контекст: | http |
Описывает таблицу перекодирования из одной кодировки в другую. Таблица для обратного перекодирования строится на основании тех же данных. Коды символов задаются в шестнадцатеричном виде. Неописанные символы в пределах 80-FF заменяются на “ ? ”. При перекодировании из UTF-8 символы, отсутствующие в однобайтной кодировке, заменяются на “ &#XXXX; ”.
При описании таблицы перекодирования в UTF-8, коды кодировки UTF-8 должны быть указаны во второй колонке, например:
Полные таблицы преобразования из koi8-r в windows-1251 и из koi8-r и windows-1251 в utf-8 входят в дистрибутив и находятся в файлах conf/koi-win , conf/koi-utf и conf/win-utf .
Синтаксис: | charset_types mime-тип . ; |
---|---|
Умолчание: | |
Контекст: | http , server , location |
Эта директива появилась в версии 0.7.9.
Разрешает работу модуля в ответах с указанными MIME-типами в дополнение к “ text/html ”. Специальное значение “ * ” соответствует любому MIME-типу (0.8.29).
До версии 1.5.4 по умолчанию вместо MIME-типа “ application/javascript ” использовался “ application/x-javascript ”.
Синтаксис: | override_charset on | off ; |
---|---|
Умолчание: | |
Контекст: | http , server , location , if в location |
Определяет, выполнять ли перекодирование для ответов, полученных от проксированного сервера или от FastCGI/uwsgi/SCGI/gRPC-сервера, если в ответах уже указана кодировка в поле “Content-Type” заголовка ответа. Если перекодирование разрешено, то в качестве исходной кодировки используется кодировка, указанная в полученном ответе.
Необходимо отметить, что если ответ был получен в подзапросе, то, независимо от значения директивы override_charset , всегда выполняется перекодирование из кодировки ответа в кодировку основного запроса.
Синтаксис: | source_charset кодировка ; |
---|---|
Умолчание: | — |
Контекст: | http , server , location , if в location |
Задаёт исходную кодировку ответа. Если эта кодировка отличается от указанной в директиве charset, то выполняется перекодирование.
Charset windows 1251 nginx
- Поисковые системы
- Яндекс
- Каталоги сайтов
- Прочие поисковики
- Агрегаторы и доски объявлений
- Практика оптимизации
- Общие вопросы оптимизации
- Частные вопросы — ранжирование, индексация, бан
- Сервисы и программы для работы с SE
- Любые вопросы от новичков по оптимизации
- Ссылочные и пользовательские факторы
- Поисковые технологии
- Doorways & Cloaking
- Трафик для сайтов
- Поисковая и контекстная реклама
- Google Adwords
- Яндекс.Директ
- Тизерная и баннерная реклама
- Общие вопросы рекламы
- Монетизация сайтов
- Партнерские программы в Интернете
- Контекстная реклама
- Google AdSense
- Рекламная Сеть Яндекса
- YouTube
- Размещение тизерной и баннерной рекламы
- Общие вопросы
- Сайтостроение
- Веб-строительство
- Статистика и аналитика
- Доменные имена
- Администрирование серверов
- Хостинг
- Безопасность
- Usability и удержание посетителей
- Копирайтинг
- Общение профессионалов
- SMM
- Семинары и конференции
- eCommerce, интернет-магазины и электронная коммерция
- Телефония и коммуникации для бизнеса
- Деловые вопросы
- Финансы
- Cчет в Яндекс.Деньгах
- Криптовалюты
- Инвестиции
- Экономика
- Правовые вопросы
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты — покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки — обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу
- О сайте и форуме
- Самое разное
- Курилка
- Встречи и сходки
- Железо и софт
8 трендов e-commerce, которых стоит ожидать в 2021 году
Telegram тестирует закрепление сообщений в личной переписке
Требуется поддерживать кодировку cp1251 и по дефолту её использовать. Есть сайты как в утф так и в cp1251. С utf все сайты работают без проблем (которые в utf-8), а вот cp1251 — никак.
Из-за этой ошибки при открытии сайтов на cp1251 (PHP) выдаётся хеадер такой:
Если сделать charset off; — то выдаёт хеадер такой же как и выше (utf-8). В server <> нет charset и вообще ничего с кодировкой связанного. override_charset on; — тестирую и на хтмл и на пхп страницах
Подскажите, что делать! Уже 3 дня мучаюсь. Если использовать charset_map, то адские иероглифы и браузер из-за них виснет. Почему он хочет charset_map использовать? Сам сайт не выдаёт хеадеров, тобишь в коде (php) нет такого. А он похоже думает, что контент сайта в utf-8. но почему?
Причём страницы ошибок и .html которые тоже в ANSI (windows-1251) — он выдаёт правильно. А PHP — все в UTF-8 выдаёт
Где собака зарыта? Хелп 🙁 Хоть какую-нибудь мысль подскажите. В какую сторону смотреть.
Подробная установка и настройка Nginx с примерами
Базовая настройка nginx не представляет каких-то сложностей на первом этапе. У nginx есть неплохая документация на русском языке. Еще лучше на английском. Практически все, что я буду рассказывать, есть там. Понятное дело, что если вы только знакомитесь с продуктом, или используете его базовый функционал, копать документацию на начальном этапе будет не очень продуктивно. Моя статья будет служить беглым обзором основных возможностей, которые я сам использовал, с моими же примерами.
По тематике некоторых разделов у меня уже есть подробные статьи. В таком случае я буду давать на них ссылки с краткими комментариями здесь. В конце статьи приведу свой типовой конфиг для nginx, который я обычно беру за основу, когда настраиваю очередной web сервер.
Установка nginx
В своей статье я не буду привязываться к конкретному дистрибутиву, так как настройка nginx одинакова везде. Формат файла один и тот же, поэтому конфигурация без проблем может мигрировать на разные системы. Править придется только пути к файлам и директориям. Тем не менее, я расскажу, как выполнить установку на популярные дистрибутивы.
Установку nginx на CentOS 7 я подробно разбирал в соответствующей статье про настройку web сервера на centos. Здесь просто перечислю необходимые шаги.
Подключаем репозиторий nginx для CentOS 7:
Вот и все. На этом установка на Centos 7 закончена. Пример установки nginx на Debian.
Подключаем репозиторий для Debian:
Импортируем ключ для проверки подлинности пакетов:
Устанавливаем nginx на Debian:
Установим nginx на Ubuntu. Подключаем репозиторий:
Выполняем установку nginx на Ubuntu:
На всех указанных системах запуск веб сервера выполняется командой:
Добавляем nginx в автозагрузку:
В последнее время большое распространение получили контейнеры, в частности docker. Довольно популярна ситуация, когда nginx работает в докере, поэтому отдельно рассмотрю вопрос установки nginx в docker, хоть там и нет ничего сложного.
Nginx в Docker
Неоспоримые преимущества от использования docker получают разработчики, поэтому они очень часто его используют. В том числе в виде контейнеров docker с nginx. Установка nginx через docker может быть выполнена из официального образа nginx в Docker Hub. Установить и запустить nginx в docker можно примерно такой командой:
- nginx01 — имя созданного контейнера, основанного на базовом образе nginx
- -p 80:80 — сопоставление порта на локальной машине, порту в контейнере. Сначала указывается локальный порт, потом внутри контейнера.
- -d — ключ, обозначающий запуск контейнера в режиме службы.
Это общий случай установки. Образ nginx в данном случае будет скачан автоматически при создании первого контейнера. Для удобства используется большее количество параметров. Для примера запустим еще один контейнер с другим названием и с расширенными параметрами.
В данном примере мы создали еще один контейнер naginx02, назначили ему порт 81 на локальной машине, в контейнер смонтировали 3 локальные директории:
/nginx/www — здесь будут лежать исходники сайта.
/nginx/conf — полная конфигурация nginx. Ее нужно будет скопировать откуда-то.
/nginx/logs — логи nginx.
Не обязательно выносить на хост все эти папки. Я показываю для примера. Вы выбирайте только то, что вам действительно нужно.
Таким образом можно легко работать с nginx с помощью docker. Можно без проблем запустить сколько угодно контейнеров с nginx, указав каждому свой порт, конфигурацию и директорию с исходниками. Для разработки это действительно удобно. Для продакшена отдельный разговор. Те, кто используют nginx в docker в production вряд ли нуждаются в данной статье.
Рестарт nginx и другие параметры командной строки
Перед тем, как двигаться дальше к настройке nginx, предлагаю пройтись по основным параметрам в командной строке. Это упростит и ускорит дальнейшую работу.
Прежде всего расскажу, как перезапустить nginx. С помощью systemctl на всех дистрибутивах это выглядит одинаково.
Перед перезагрузкой nginx, рекомендую выполнить проверку конфигурации:
Еще одна важная команда, с помощью которой можно применить новую конфигурацию nginx без остановки и перезапуска веб сервера. Будет запущен новый рабочий процесс с новой конфигурацией, а старые процессы плавно завершатся.
Следующая команда помимо тестирования конфигурации, выводит полный конфиг на экран. Вывод можно направить в отдельный файл и там проанализировать. Это удобно, когда у вас конфигурация состоит из множества вложенных конфигов, правильность которых трудно оценить разом.
Так же бывает полезно посмотреть полную информацию о версии nginx, параметрах сборки, модулях и т.д.
Например, мне эта информация была нужна, когда я делал собственную сборку nginx c поддержкой tls 1.3 и модулем сжатия brotli.
В принципе, на этом все. Не припоминаю, чтобы я использовал что-то еще. Плавно переходим к конфигурации nginx.
Виртуальные хосты
После дефолтной установки nginx у вас уже будет один виртуальный хост, который описан конфигом default.conf. Обычно конфиги с виртуальными хостами расположены в директории /etc/nginx/conf.d. Здесь, в отличие от Apache, структура размещения конфигурационных файлов одинаковая на всех дистрибутивах, что очень удобно.
Что такое виртуальный хост? Попробую объяснить своими словами. Это конфигурационный файл, который описывает настройку условно одного домена. Для удобства, каждый виртуальных хост выносят в отдельный конфиг, но никто не мешает вам все это описывать в общем конфигурационном файле. Дело в том, что если доменов у вас много, то работать в одном большом конфиге не удобно, поэтому я рекомендую вам придерживаться схемы файлов конфигурации, когда один конфиг описывает параметры одного домена.
Виртуальные хосты наследуют параметры из основного файла конфигурации nginx.conf, но эти параметры могут быть переопределены в конкретном виртуальном хосте. То есть можно задать дефолтные параметры для всех сайтов, но в случае необходимости переопределить какой-то параметр в конкретном виртуальном хосте. Вот типичный пример конфига.
Все не указанные явно в этом виртуальном хосте параметры будут унаследованы из основного файла конфигурации nginx.conf. Допустим, вам надо по какой-то причине отключить сжатие gzip на этом хосте и указать кодировку windows-1251. Тогда конфиг приобретет следующий вид.
С помощью виртуальных хостов в nginx вы можете очень гибко настраивать конфигурацию каждого домена. Как минимум я рекомендую для каждого домена делать отдельно:
- директорию с исходниками сайта;
- директорию с логами;
- в некоторых ситуациях отдельный php-fpm пул для каждого сайта или группы сайтов.
Более полный пример настройки виртуального хоста для реального сайта на wordpress смотрите в отдельной статье по настройке web сервера. Мы же переходим к настройке location.
Настройка location в конфигурации
Как вы могли заметить, в предыдущем примере я использовал 2 разных location для виртуального хоста. Постараюсь простыми словами рассказать, что это такое, как использовать и для чего вообще нужно.
С помощью location в nginx вы можете управлять конфигурацией в зависимости от URI запроса. Если в виртуальных хостах мы могли переопределять настройки в зависимости от имени домена, то тут мы спускаемся на уровень ниже и управляем параметрами в зависимости от пути запроса. В примере с виртуальными хостами у меня было 2 location:
- / — корень сайта, перехватывает вообще все запросы к домену.
\.php$ — запросы к файлам с расширением php. То есть если в запросе указан путь к файлу .php, то к нему применяется параметр fastcgi_pass и запрос отправляется на обработку к php-fpm.
Location можно задавать префиксной строкой или регулярным выражением. В регулярных выражениях используются модификаторы
* Без звездочки учитывается регистр, со звездочкой нет. Обработка location в конфигурационном файле идет в следующей последовательности:
- Первыми проверяются префиксные строки. Совпадения запоминаются.
- Дальше проверяются регулярные выражения в том порядке, как они перечислены в конфигурационном файле. Проверка по регулярным выражениям прекращается сразу же после совпадения. Если совпадение не было найдено, используется запомненный ранее префикс.
Так же в location может использоваться префикс = Он означает точное совпадение запроса и заданного location. После такого совпадения, остальные проверки сразу же прекращаются. Рекомендуется использовать этот префикс, если у вас огромное количество конкретных запросов. Используя префикс = для них, вы снизите нагрузку на сервер, так как запросы не будут проверяться по всем правилам.
В крупном сайте может быть огромное количество различных location. Вот несколько простых реальных примеров из моей практики.
На своем сайте я решил отказаться от использования amp страниц, выключил их и сделал перенаправление с этих страниц на обычные. В данном примере amp располагались по исходному урлу с добавлением /amp/ в конец пути.
В этом примере укажем максимальный срок хранения картинок и шрифтов в кэше а так же отключим для них логирование.
Закроем доступ к директории .git на сайте.
Запретим исполнение скриптов в перечисленных директориях.
И так далее. Думаю, смысл понятен. Примеров может быть огромное количество. Location важный параметр конфигурации в настройке nginx. Немного информации на эту тему можно посмотреть в соответствующем разделе документации.
Работа nginx с php-fpm
В предыдущих разделах я уже показал примеры конфигурации, где запросы по определенным URI перенаправляются на php-fpm. Еще более подробно я рассмотрел этот вопрос в отдельной статье по настройке php-fpm. Сейчас просто покажу на реальном примере, как выглядит взаимодействие nginx и php-fpm.
Php-fpm может слушать как сокет unix, так и tcp порт. Эти настройки задаются в конфиге пула. Это может быть либо
В зависимости от того, в каком режиме работает php-fpm, зависят настройки в nginx.
Вот примерный конфиг php-fpm для пула www.conf на виртуальной машине с 1Gb памяти.
Чтобы заработал php в nginx через php-fpm, достаточно убедиться, что php-fpm работает и указать в виртуальном хосте location для php. Пример реальных настроек для wordpress сайта.
В целом все. Этого достаточно для настройки связки nginx + php-fpm. Типовой ошибкой в данном случае является то, что nginx не имеет доступа к unix сокету php-fpm. По-умолчанию после установки он запускается с правами apache. Если пользователя не исправить на nginx, то у веб сервера не будет доступа к сокету, php не заработает. В своем примере конфига php-fpm я указал пользователя правильно.
Настройка SSL сертификата
Далее рассмотрим момент с настройкой ssl сертификатов в nginx. В общем случае с этим не должно быть каких-то проблем. Тут все просто. Можно глобально задать настройки ssl для всех виртуальных хостов, а можно отдельно в каждом. Вот пример настроек ssl для nginx.conf.
Здесь уже включена поддержка TLS 1.3 и соответствующие шифры. Сейчас не готов прокомментировать именно такой выбор шифров. В свое время, перед настройкой TLS 1.3 я изучил этот вопрос и собрал такой набор, который везде использую.
Часто возникают споры насчет директивы resolver. На dns сервер 8.8.8.8 есть нарекания по стабильности. Так что выбор dns сервера остается за вами. С подобными настройками ssl вы получите рейтинг A+.
Для генерации файла dhparam.pem, воспользуйтесь командой:
Процесс длится долго, до получаса на слабых виртуалках. Этот файл нужен для повышения безопасности и получения максимального рейтинга. Насколько этот параметр критичен в реальности, не берусь судить. Если тороплюсь, то настраиваю без него. Подробный разбор параметров ssl можно посмотреть в статье на хабре.
В виртуальном хосте надо будет добавить настройки, касающиеся непосредственно сертификатов, а так же указать, что сервер слушает 443 порт.
Редирект с http на https
Добавим переадресацию с http на https. Для этого добавляем в настройки виртуального хоста еще одну директиву server.
Проксирование запросов
Nginx очень производительный веб сервер, поэтому его часто используют в качестве Reverse Proxy для других служб и серверов. Подробно вопрос проксирования запросов в nginx с помощью proxy_pass я рассмотрел отдельно. Сейчас же в двух словах объясню, что это такое. Допустим, у вас есть какой-то сервис на отдельном сервере и вы ходите перенаправлять на него часть запросов с вашего сайта. Для этого вы делаете отдельный location и указываете, что все запросы по определенному правилу нужно перенаправлять на этот сервер.
Все запросы с урлами, содержащими /forum/ будут перенаправлены на отдельный сервер, где трудится тяжелый форум со своей базой данных и своими настройками. Им может управлять другой администратор и вообще он не имеет к вам никакого отношения. Таким образом, большой проект можно разделить на части с делегированием полномочий. Но это отдельная история.
Nginx proxy_pass удобно использовать разработчикам для проксирования запросов в разные docker контейнеры, которые подняты на рабочей машине на разных портах. Можно перенаправлять не только отдельные урлы, но и весь сайт. Допустим, вы делаете какие-то фильтрации трафика на стороне сервера с nginx, а потом все запросы отправляете на исходный сайт. Тогда делаете простую настройку для проксирования:
Все запросы уходят на сторонний сервер. Частным случаем проксирования в nginx является работа в связке с Apache, о чем я расскажу далее.
Nginx в связке с Apache
Популярным кейсом работы nginx является работа в качестве Reverse Proxy для Apache. Лет 5-10 назад, когда nginx был не очень распространен, это было очень популярное решение. Сейчас Nginx во многих областях полностью заменил Apache, но тем не менее, пока еще не до конца. К примеру, очень популярный в России движок для сайтов Bitrix до сих пор требует в качестве web сервера Apache.
Покажу на простом примере, как Nginx настроить в качестве front-end к Apache. Статические данные будет обрабатывать сам nginx, а динамические запросы перенаправлять на apache.
Для начала вам необходимо настроить apache стандартным образом, с той лишь разницей, что слушать он должен не привычный 80-й или 443 порт, а, к примеру, 8080. Далее в настройках виртуального хоста указываете для каких запросов будет перенаправление на apache. Для примера отправим туда все, что не является статичным контентом. Создаем 2 location:
- Статика, которую будет напрямую отдавать Nginx.
- Все остальные запросы, которые будет обрабатывать Apache.
В данном примере Nginx и Apache работают на одном сервере. Но это не обязательно. Web сервер с apache вы без проблем можете разместить на другой машине. Отдельно будет стоять вопрос определения реальных ip адресов клиентов на сервере с Apache. Я его рассмотрел подробно в статье про nginx revers proxy, ссылку на которую привел в предыдущем разделе.
Балансировка нагрузки
Nginx может выступать в качестве балансировщика. Настройку балансировки в nginx я так же подробно рассматривал отдельно. Все подробности в статье. Здесь кратко упомяну, что это такое. Nginx умеет распределять нагрузку между несколькими серверами. Правила распределения настраиваются, как и количество серверов. Покажу как это делать на предыдущем примере с apache.
Допустим, у вас очень нагруженный сайт. А нагрузить Bitrix без настроенного кэширования, очень просто. Вы хотите добавить еще один сервер с Apache, чтобы распределить нагрузку между двумя серверами. Сразу скажу, что это не такой простой вопрос, как может показаться вначале. Со стороны nginx настройки действительно простые, но нужно будет рассмотреть отдельно вопрос общего файлового хранилища для обоих серверов и общей базы данных. Ее, скорее всего, тоже нужно будет выносить на отдельный сервер, хотя и не обязательно. Если nginx будет раздавать статику, то доступ к файлам должен быть и у него. В общем, тут нужно хорошенько все продумать и подготовить. Может как-нибудь напишу статью с примером на данную тему.
Итак, распределим нагрузку между двумя бэкендами с Apache. Вот конфигурация виртуального хоста в этом случае.
В данном примере балансировки нагрузки, nginx отдает всю статику, а 2 сервера с apache обрабатывают все остальные запросы.
Настройка редиректов и rewrite правил
Rewrite это то, что в первую очередь не позволяет отказаться от Apache. Многие проекты имеют массу rewrite правил в .htaccess, который поддерживает apache. Перенос этих правил в nginx не всегда прост и очевиден. Есть средства по автоматической конвертации правил rewrite из формата apache в формат nginx, но они далеко не всегда помогают. Пример такого сервиса — https://winginx.com/ru/htaccess. В идеале, такую конвертацию следует проделывать вручную, подключая голову 🙂
Это что касается конвертации правил из апача. А в целом rewrite правила в nginx это очень мощный инструмент. Вот несколько примеров правил.
С помощью rewrite можно отрезать у доменных имен www. Лично я считаю эту добавку к адресу сайта ненужным рудиментом и отрезаю на своих сайтах. Пример правила rewrite для замены www на запрос без него.
Это правило rewrite все запросы к домену с www переадресовывает на запрос без www. Тут это просто пример работы механизма. В данном конкретном случае, редирект www лучше сделать с помощью return. Это более элегантное и быстрое решение, так как не придется обрабатывать лишнюю регулярку. На практике конкретно с www лучше поступить вот так:
Синтаксис rewrite запросов выглядит следующим образом:
В моем примере получаем следующие элементы правила:
- ^ — регулярное выражение;
- https://example.com$request_uri — url, на который заменяем;
- permanent — флаг, который возвращает постоянное перенаправление с кодом 301.
Вот еще один пример, который я уже приводил в разделе про location. Я настраиваю замену страниц с /amp/ на конце на обычный url без /amp/. То есть просто его обрезаю.
Полезным является еще одно правило rewrite, которое к ссылкам в конце без слеша добавляет слеш. То есть заменяет ссылку вида http://example.com/page на http://example.com/page/
Много видел в сети примеров, где rewrite используют для перенаправления запросов с http на https. Как и в случае с заменой www, так лучше не делать. Тем более не стоит это делать через условия if, например вот так:
Это рабочий вариант, но в данном случае return вместо rewrite будет работать более эффективно, затрачивая меньше ресурсов web сервера. То же самое относится к примерам, где требуется замена имени домена в случае переезда. Вместо rewrite лучше использовать return. То есть делать не вот так:
Такой редирект с одного домена на другой быстрее работает.
Принципиальная разница между rewrite и return в том, что в rewrite переписывается только та часть исходного URL, которая соответствует регулярному выражению, а в return весь URL-адрес переписывается на указанный URL-адрес. Из этой особенности следует то, что return работает быстрее rewrite, поэтому там, где можно использовать return, лучше использовать именно его. Условно, return следует использовать там, где требуется постоянная замена адреса, а rewrite где требуется временное изменение запроса в силу каких-то обстоятельств.
Вот пример, где без rewrite не обойтись. Допустим, у вас есть какой-то обработчик запросов, которому нужно передавать различные урлы в определенном формате. К примеру, пользователи запрашивают урл http://example.com/linux/ubuntu, а нам надо его преобразовать в такой — http://example.com/linux.php?distro=ubuntu. Делаем это с помощью следующего правила rewrite.
Еще пример, как сделать постоянное перенаправление с одной страницы на другую. Как обычно, можно сделать двумя способами, с помощью rewrite или return. Более правильно использовать return. Меняем адрес http://example.com/linux/ubuntu/ на http://example.com/windows/win10/
Вот нежелательный вариант, который тем не менее постоянно рекомендуют в разных статьях. Ошибки тут нет, но с return более правильно.
Фух, надеюсь с return и rewrite более ли менее понятно объяснил. Есть еще для перенаправлений try_files. Я немного плаваю в этой теме, поэтому решил не добавлять эти правила, чтобы вас не запутать и не наговорить неправды. К примеру, вопрос со слешами на конце урла в wordpress можно решить с помощью try_files таким образом:
Проверяется запрос со слешом, потом без него, если ничего не найдено, запрос уходит на index.php с параметрами. То есть не важно, что наберет пользователь, у него в любом случае будет открыта та или иная страница. Более подробно о различных правилах перенаправления можно почитать в этой англоязычной статье. Это наиболее полная информация по данной теме, что мне нагуглилась.
502 bad gateway и другие ошибки nginx
Ошибка 502 bad gateway знакома многим пользователям интернета, не только системным администраторам. Ее рано или поздно можно увидеть на любом сайте. Что она означает? В общем случае, это значит, что на веб сервере какие-то проблемы.
Ошибка 502 описана в RFC Hypertext Transfer Protocol (HTTP/1.1) в разделе 6.6.3. Там говорится, что во время обработки запроса веб сервер, в данном случае nginx, не получил ответ от какого-то бэкенда. Расскажу, что это обычно значит на практике.
Допустим, у вас nginx работает в связке с apache или php-fpm. Вы видите описываемую ошибку. Причин может быть две:
- Службы php-fpm или apache перестали отвечать, потому что просто упали. В таком случае, nginx будет показывать всем пользователям ошибку 502, пока бэкенд не начнет отвечать.
- Служба просто не справляется с нагрузкой. Ошибка будет только у части пользователей, а у других все будет нормально.
То же самое может произойти, если вы настроили проксирование запросов через proxy_pass на какой-то другой сервер и этот сервер перестал отвечать. Nginx будет показывать ошибку 502 bad gateway в данном случае.
Для того, чтобы исправить 502-ю ошибку, надо разобраться, с чем конкретно она связана. Если бэкенд просто упал, то надо его поднять. Если же причина не в этом, то надо более детально разбираться. Чаще всего в логах ошибок nginx есть вся информация для решение проблем с ошибкой 502. Наиболее распространенная ситуация с этой ошибкой при работе в связке с php-fpm в том, что php-fpm просто не выдерживает нагрузки, либо неправильно настроен. Возможно, у него не хватает процессов для обработки всех запросов. Тогда часть запросов будут возвращать ошибку.
Вот типичный пример ошибки 502 при работе с php-fpm. Пользователь видит ошибку. Идем смотреть лог ошибок виртуального хоста. Видим там такую строку:
В данном случае php-fpm просто упал и перестал обрабатывать запросы.
Я достаточно часто встречаюсь с этой серверной ошибкой. Иногда разработчики напрограммируют таких конструкций, что они валят php-fpm по какой-то причине. Причем, если проект уже сдали и он давно работает, никто с этими ошибками разбираться уже не хочет. Тогда я просто ставлю костыль — автоматически перезапускаю php-fpm с помощью zabbix, ели вылезает ошибка 502 bad gateway в nginx. Такие вещи иногда годами работают и в целом всех устраивают.
Вы можете настроить внешний вид страницы с ошибкой. То, что я показал на скрине — стандартный вид ошибки 502 bad gateway в nginx при отсутствии каких-то настроек на этот счет. Вы же можете установить свою страницу при возникновении этой ошибки. На ней можно написать, к примеру, что на сервере ведутся технические работы и скоро он заработает вновь. В каждый виртуальный хост можно установить свою страницу с ошибкой. Настраивается она в секции server.
В данном случае мы на все ошибки с кодами 500 502 503 504 показываем страницу /usr/share/nginx/html/error50x.html.
Ошибка 404 not found
Еще одна популярная ошибка nginx — 404 not found.
Тут все понятно и без объяснений — пользователь открывает ссылку, а документа по этой ссылке нет. Иногда бывает не очевидно, почему по ссылке выходит 404 ошибка. В таком случае рекомендую сразу смотреть лог ошибок. Вот пример.
Ссылка ведет на документ, который должен быть в директории /usr/share/nginx/html/, но его там нет. Когда настраиваются алиасы, часто возникают такого рода ошибки. Вроде все настроил, а все равно 404 ошибка. Идешь смотреть лог и видишь, что реально nginx ищет не там документ, где ты ожидал, согласно настройкам. Надо просто все еще раз перепроверить. В статьях про установку zabbix я регулярно вижу вопросы, связанные с 404 ошибкой. Люди просто ошибаются при настройке веб сервера.
Страницу с этой ошибкой можно так же кастомизировать. Это делают практически все крупные сайты. Вот, к примеру, как выглядит эта ошибка у меня на сайте.
В данном случае внешний вид страницы с ошибкой формирует сам wordpress. Но вы так же можете это настроить самостоятельно через nginx.
Переменные в nginx
В примерах выше с редиректами я использовал переменные, но совершенно не останавливался на них и не пояснял, что они значат. Многие из них понятны по названиям, например:
- $args — аргументы в строке запроса;
- $request_uri — первоначальный URI запроса целиком (с аргументами);
- $scheme — схема запроса, http или https.
Полный список переменных можно посмотреть в документации. Когда вы отлаживаете сложную конфигурацию nginx с множеством переменных, бывает удобно выводить эти переменные в отдельные заголовки, а потом смотреть их во время отладки. Просто добавьте в конфигурацию виртуального хоста запись переменной примерно так.
Вместо R-var можете написать что угодно, это просто название записи. Далее в DevTools в Chrome можете смотреть эти заголовки.
Кэширование в nginx
Тема кэширования очень обширна. Много копий сломано о том, какое и где кэширование лучше применять. В том же wordpress существует огромное множество плагинов для кэширования. Nginx может самостоятельно хранить и управлять кэшом. В некоторых случаях это будет эффективнее, чем использовать плагины. Но все сильно зависит от конкретного проекта.
Кэшировать Nginx может разные вещи:
- Статику, которую получает с удаленного сервера, сохраняет себе и раздает быстрее, чем удаленный сервер.
- Динамику, превращая ее в статику и раздавая самостоятельно, без обращения к бэкенду.
С кэширвоанием статики все более ли менее понятно. Сохраняем файлы и отдаем их сами. А вот с кэшированием динамических страниц есть очень много нюансов. Конечно, удобно сформировать один раз динамическую страницу php, сохранить ее как html и раздавать. А что делать со счетчиком просмотров на странице, с комментариями, со списком последних статей, после публикации новой? Это первое, что приходит в голову. Таких моментов может быть очень много. В реальном проекте скорее всего не получится просто взять и включить кэширование.
Конкретно с WordPress я обычно поступаю следующим образом. Кэширование nginx я не использую. Вместо этого я использую плагин WP Total Cache. Он формирует статические html страницы по заданным в его настройках параметрам. А дальше я эти страницы отдаю напрямую через nginx, минуя вообще ядро WordPress. За счет этого достигается максимальное быстродействие. Вот пример настроек Nginx из секции server виртуального хоста для отдачи кэша WordPress.
Сначала идут проверки для добавления исключений к некоторым запросам, для которых кэширование не будет работать. А потом отдается статика из директории с кэшом. Если для заданного URI кэша нет, он уходит дальше в обработку.
В данном случае используется именно плагин WP, а не кэш nginx только из-за удобства управления кэшом через панель управления сайтом. Сам плагин делает ровно то же самое, что может делать nginx. Кэш в самом nginx настраивается следующим образом.
Сначала добавляются настройки кэширования в nginx.conf. Дальше речь пойдет о кэшировании динамики через fastcgi.
- fastcgi_cache_path — директива для объявления кэша для fatcgi;
- /var/cache/nginx/php — директория, где будут храниться файлы кэша;
- levels=1:2 — уровень вложенности каталогов в директории с кэшом;
- keys_zone=php_cache — название зоны;
- max_size=3g — размер директории с кэшом в 3Гб.
Не забудьте создать указанную директорию для кэша /var/cache/nginx/php. В конфигурацию виртуального хоста добавляем параметры кэширования в location с php.
Кэшируем ответы с кодом 200 на 120 минут.
Для кэширования запросов с ответами от бэкенда через proxy_pass, необходимо использовать директиву proxy_cache_path.
И далее в вирутальном хосте.
Подробнее о кэшировании читайте в блоге nginx. Там очень много нюасов. Как минимум надо аккуратно прорабатывать исключения, чтобы в кэш не попадало то, что там быть не должно. Например, cookie или страницы из закрытой административной части.
Auth basic, доступ по паролю или ограничение по ip
Покажу на простых примерах, как в nginx настроить ограничения доступа по ip, имени пользователю и паролю (Auth basic авторизация). Начнем с простого. Закроем доступ к определенной папке на сайте всем подряд и разрешим только после ввода имени пользователя и пароля. Для этого добавляем в виртуальный хост, в нужный location следующие параметры.
Теперь нам надо создать файл с именем пользователя и паролем.
Если получите сообщение, что у вас нет утилиты htpasswd, установите соответствующий пакет.
Перечитайте конфигурацию nginx и проверяйте. Теперь доступ к /secret возможен только после авторизации по имени пользователю и паролю.
Настроим ограничение доступа по ip в nginx. Для этого достаточно добавить в свойства location или всего виртуального хоста следующие правила доступа.
Если нужен запрет доступа ко всему сайту сразу, то ставьте это ограничение в секцию server.
Если вам нужно настроить ограничение доступа по ip на основе стран или регионов, то читайте мою отдельную статью на эту тему — блокировка доступа к сайту по странам.
Мониторинг nginx
Для настройки мониторинга nginx, необходимо внести некоторые параметры в конфигурационный файл nginx.conf. После этого nginx сам будет отдавать базовую информацию о состоянии сервера с помощью модуля ngx_http_stub_status_module. Добавляем в секцию http следующее.
Перезапускаем nginx и проверяем. Я разрешил отдавать состояние о своем статусе только при запросе с локального сервера, где сам nginx работает. Поэтому смотрим через консоль сервера.
Какие метрики мы здесь видим:
- Active connections — количество активных клиентских соединений.
- accepts — число принятых клиентских соединений.
- handled — число обработанных соединений.
- requests — число клиентских запросов.
- Reading — число соединений, в которых nginx в настоящий момент читает заголовок запроса.
- Writing — число соединений, в которых nginx в настоящий момент отвечает клиенту.
- Waiting — число бездействующих клиентских соединений в ожидании запроса.
Что делать с этими данными — решать вам в зависимости от того, какую систему мониторинга вы используете. Более подробно о мониторинге nginx читайте в отдельной статье.
Пример универсального конфига для nginx
В завершении своей статьи про настройку nginx, я хочу привести шаблон универсального конфига, который я обычно использую при настройке веб сервера. Сил уже нет писать статью, поэтому привожу его без подробных комментариев. Надеюсь сами разберетесь с помощью документации. Статью писал несколько дней и под конец уже устал 🙂
На этом по базовой настройке nginx все. Надеюсь, было полезно.