Инструменты пользователя

Инструменты сайта


linux:nginx

Nginx

Сведения

:!: Общее

Эффективное использование ресурсов, отзывчив под нагрузкой.
Используется как веб так и прокси сервер.
Спроектирован на базе асинхронных неблокирующих event-driver алгоритмов, сервер однопоточный и не создает процессы под каждое соединение, использование ресурсов относительно равномерно.

Динамический контент
Nginx не имеет возможности самостоятельно обрабатывать запросы к динамическому контенту (например php), для этого он передает запрос внешнему процессу (например php-fpm) и ожидает результата.
На каждый запрос создается отдельное соединение с процессом. (плюс в экономии на статических запросах).
Взаимодействие может быть по одному из следующих протоколов: http, FastCGI, SCGI, uWSGI, memcache.

Интерпретация запросов
В отличии от сервера Apache, Nginx интерпретирует запросы в первую очередь как URL а не как пути в файловой системе.
Во многом из-за своего Альтер Эго в роли прокси сервера, из-за чего и не реализует поддержку файлов .thaccess.

Модули
В отличии от Apache, в Nginx модули не являются динамическими, а должны компилироваться с ядром сервера.

Совместное использование с Apache
Очень частая практика использования обоих серверов вместе, Nginx ставится в качестве реверс-прокси, т.е. фронтенд а Apache бэкенд.
Nginx самостоятельно обслуживает статический контент а динамический передает Apache.
в такой конфигурации можно ставить несколько бэкендов, таким образом хорошо масштабировать систему.

Установка

Подключаем репозиторий:

# echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list

Импортируем ключ для него:

# curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

Устанавливаем:

# apt update && apt install nginx

Проверяем/включаем запуск/автозапуск

# systemctl start/enable nginx

Конфигурация

Проверка конфигурации:

# nginx -t

Вывести полный конфиг на экран:

# nginx -T

Применение новой конфигурации без перезагрузки сервера:

# nginx -s reload

Информация о версии и модулях:

# nginx -v

Виртуальные хосты

Виртуальный хост - это конфиг, который описывает настройку одного домена, для удобства каждый виртуальный хост в отдельном конфиге, но можно это делать и в общем.
Конфиги с виртуальными хостами расположены в /etc/nginx/conf.d/
Виртуальные хосты наследуют параметры из основного файла конфигурации - /etc/nginx/nginx.conf, эти параметры могут быть переопределены в каждом виртуальном хосте. Наследуются все явно не указанные параметры.

Location

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

  • ~ - учитывается регистр
  • ~* - не учитывается)

Сначала проверяются префиксные строки, совпадения запоминаются, затем регулярные выражения, в порядке перечисления, если совпадает, то исполняется, если нет, то исполняется запомненный ранее префикс.
Так же, можно использовать префикс =, он означает точное совпадение запроса и заданного location. После совпадения, остальные проверки прекращаются.

Пример: Укажем максимальный срок хранения картинок в кэше и отключим логирование:

location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|swf|ttf|svg)$ 
{
  access_log off;
  expires 1y;
}

Пример: Запретим исполнение скриптов в перечисленных директориях:

location ~* /(images|cache|media|logs|tmp)/.*.(php|pl|py|jsp|asp|sh|cgi)$ 
{
  return 404;
}

Работа с php-fpm

Устанавливаем и настраиваем php-fpm.
Далее, достаточно только указать в виртуальном хосте Location для php:

location ~* \.php$ 
{
  fastcgi_pass unix:/run/php/php7.1-fpm.sock;
  include         fastcgi_params;
  fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
  fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
}

Расширенный пример:

location ~ \.php$ 
{
  try_files  $uri =404;
  fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
  fastcgi_index index.php;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
  fastcgi_param QUERY_STRING $query_string;
  fastcgi_param REQUEST_METHOD $request_method;
  fastcgi_param CONTENT_TYPE $content_type;
  fastcgi_param CONTENT_LENGTH $content_length;
  fastcgi_param HTTPS on; # включать, если сайт по https работает
  fastcgi_intercept_errors on;
  fastcgi_ignore_client_abort off;
  fastcgi_connect_timeout 60;
  fastcgi_send_timeout 180;
  fastcgi_read_timeout 180;
  fastcgi_buffer_size 128k;
  fastcgi_buffers 4 256k;
  fastcgi_busy_buffers_size 256k;
  fastcgi_temp_file_write_size 256k;
}

Прокси

Проксирование происходит с помощью блока Location, и директивы proxy_pass.
Пример: Все запросы содержащие /forum/ будут направлены на отдельный сервер

location /forum/ 
{
  proxy_pass http://192.168.13.31; 
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_redirect default;
}
:!: Пример с заббиксом

По умолчанию apache заббикса слушает 80, переводим его на другой, например 8080, так же задаем локальный адрес для прослушивания
Nginx может по дефолту занять 8080, чекаем этот момент

Далее в nginx редирект с 80 на 8080

server {
    listen 80;
    server_name zabbix.mydomain.ru;
    root /usr/share/nginx/html;
    index index.html index.htm;
        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_set_header Host $host;
            proxy_set_header Proxy-IP $remote_addr;
    }
}

Обработка https, прием и редирект 443, редиректим на 8080

server {
	listen 443 ssl http2;
	server_name zabbix.mydomain.ru;
	root /usr/share/nginx/html;
	index index.html index.htm;
 
	ssl on;
	ssl_certificate     /etc/zabbix/zabbix_ssl/Zabbix.crt;
	ssl_certificate_key /etc/zabbix/zabbix_ssl/Zabbix.key;
 
	location / {
		proxy_pass http://127.0.0.1:8080;
 
		proxy_set_header Host $host;
		proxy_set_header Proxy-IP $remote_addr;		
	}
}

Далее меняем редирект с 80го, теперь не на 8080 а на 443, 8080 закрыт извне, т.к. заббикс слушает только локалхост
Перевод можно такой, перенаправляет вообще все запросы на защищенный порт

server {
	listen 80 default_server;
	server_name _;
	return 301 https://$host$request_uri;
}

Связка с Apache

Сначала настраиваем Apache как обычно, только указываем ему нестандартный порт, например 8080.
Далее в настройках виртуального хоста настраиваем Location.
Пример: Перенаправление всего динамического контента, тут 2 блока Location:

  • Статика, которую возвращает сам nginx
  • Все остальные запросы, передаются Apache
server 
{
  listen 80;
  server_name example.com www.example.com;
 
  location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff|woff2|swf|ttf|svg|html|txt)$ 
  {
    root   /var/www/example.com/public;
    expires 1y;
  }
 
  location / 
  {
    proxy_pass http://127.0.0.1:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout    120;
    proxy_send_timeout    120;
    proxy_read_timeout    180;
  }
}

Пример: Два бекенда

upstream backend 
{
  server 192.168.0.10:8080;
  server 192.168.0.11:8080;
}
 
server 
{
  listen 80;
  server_name example.com www.example.com;
 
  location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff|woff2|swf|ttf|svg|html|txt)$ 
  {
    root   /var/www/example.com/public;
    expires 1y;
  }
 
  location / 
  {
    proxy_pass http://127.0.0.1:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout    120;
    proxy_send_timeout    120;
    proxy_read_timeout    180;
  }
}

Тут стоит уделить внимание расположению в сети общих ресурсов этих серверов, таких как DB, FTP и пр.

Context (блоки)

Конфиг содержит древовидную структуру, определен наборами фигурных скобок, эти области называются контекстами. Контексты вкладываются друг в друга, заданные директивы наследуют вложенными контекстами, могут переопределяться

:!: Основные директивы

Main
Контекст Main базовый, глобальный, по умолчанию присутствует всегда, директива вне контекстов, содержится в контексте main

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

Http
Содержит все директивы и другие контексты, необходимые для обработки соединений HTTP или HTTPS
Так же является дочерним от main, одноранговые с events, не вкладываются друг в друга

Содержит значения по умолчанию для каждого виртуального сервера, определенного внутри

Server
Обычно объявляется внутри http, может быть объявлен несколько раз. Виртуальный хост, набор параметров для обработки запросов, разные хосты для разных запросов например

Главные директивы для выбора вирт хоста:

  • «listen» - комбинация ip и порта, которую прослушивает данный блок
  • «server_name» - так же используется для выбора, если есть несколько блоков в одинаковыми «listen» то будет проверяться заголовок запроса «Host» и на основании этого делаться выбор

Location
Выбирается исходя из клиентского запроса, алгоритмом сопоставления
Так же, их может быть несколько, могут быть вложены друг в друга (что тоже может быть полезно). Определение находится в строке заголовка

Блоки «location» дополнительно делят обработку запросов внутри блока «server», на основании «url» запроса

upstream
Используется для определения пула серверов для проксирования. Находится в блоке «http» (только ли ?)

Затем контекст «Upstream» может ссылаться на имя в пределах блоков «server» или «location» для передачи запросов определенного типа в пул серверов. Внутри пула используется выбор хоста (round-robin), таким образом происходит балансировка нагрузки

Другие
if
Позволяет настроить условное ветвление

limit_exept
Позволяет задать ограничения на использование HTTP-методов, можно разрешать определенным адресам например

Управление

Мониторинг

Для настройки мониторинга необходимо внести изменения в конфиг nginx.conf.
После этого сервер сам предоставляет кое какие данные с помощью ngx_http_stub_status_module.
Добавляем в секцию http:

server 
{
  listen 127.0.0.1:80;
  server_name status.localhost;
  keepalive_timeout 0;
  allow 127.0.0.1;
  deny all;
  location /server-status 
  {
    stub_status on;
  }
 access_log off; 
}

После перезапуска, данные доступны (только с локального сервера, как указанно выше), командой:

# curl http://localhost/server-status
  • Active connections - количество активных клиентских соединений.
  • accepts - число принятых клиентских соединений.
  • handled - число обработанных соединений.
  • requests - число клиентских запросов.
  • Reading - число соединений, в которых nginx в настоящий момент читает заголовок запроса.
  • Writing - число соединений, в которых nginx в настоящий момент отвечает клиенту.
  • Waiting - число бездействующих клиентских соединений в ожидании запроса.

Журналы

Настройка журналов указана в основном конфиге /etc/nginx/nginx.conf, так же может быть переопределена в виртуальных хостах.
Основной синтаксис: `type_log` `path_log_file` `format_log`;
Может быть включен в любой блок конфига, либо во все (http, server или location).
Даже рекомендуется делать отдельные файлы для каждого блока.
По умолчанию располагаются в /var/log/nginx/

Журнал доступа

В журнал доступа (access_log) регистрирует каждый запрос клиента.

:!:
http 
{
  access_log  /var/log/nginx/access.log;
 
  server 
  {
    server_name domain.ru
    access_log  /var/log/nginx/domain.access.log;
  }
}

Перенаправление логов в stdout
«AccessLog» обычно в хосте, errors в общем блоке
Даже при такой конфигурации, error почему то все равно создает файл в «/var/log/nginx», потому что при запуске используется дефолтный, иначе как сообщить если ошибка в конфигурации

(...)
error_log /dev/stdout error;
 
    http {
      server {
        access_log /dev/stdout;
        (...)
      }
    }

Если формат не указан явно, используется формат по умолчанию:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

Журнал можно отключить:

access_log  off;

Журнал ошибок

error_log log_file log_level

Третий параметр указывает уровень протоколирования (каждый уровень включает в себя все нижестоящие):

  • debug – отладка сообщений.
  • info – информационные сообщения.
  • notice – Уведомления.
  • warn – Предупреждения.
  • error – Ошибки при обработке запроса (по умолчанию).
  • crit – Критические вопросы. Требует быстрых действий.
  • alert – Оповещения. Действие должно быть принято немедленно.
  • emerg – Чрезвычайная ситуация. Система находится в нерабочем состоянии.

Параметры

:!: Перечень

worker_processes -

worker_connections -

worker_cpu_affinity -

-

Примеры

:!: Docker minimal

Dockerfile

FROM nginx
COPY index.html /usr/share/nginx/html/
COPY default.conf /etc/nginx/conf.d/

Штатный конфиг nginx (из контейнера, основной)

user  nginx;
worker_processes  auto;
 
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;
 
 
events {
    worker_connections  1024;
}
 
 
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
 
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
 
    access_log  /var/log/nginx/access.log  main;
 
    sendfile        on;
    #tcp_nopush     on;
 
    keepalive_timeout  65;
 
    #gzip  on;
 
    include /etc/nginx/conf.d/*.conf;
}

Штатный конфиг в подключаемой папке (conf.d)

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;
 
    #access_log  /var/log/nginx/host.access.log  main;
 
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
 
    #error_page  404              /404.html;
 
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}
 
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}
 
    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

SSL конфиг

server{
        listen 443 ssl;
        server_name my-super-host;
 
        ssl_certificate /etc/nginx/certs/test.pem;
        ssl_certificate_key /etc/nginx/certs/test.key;
 
        location / {
                root /usr/share/nginx/html;
                index index.html;
        }
 
        location = /50x.html {
                root   /usr/share/nginx/html;
        }
}

Генерация самоподписанного серта

openssl req -x509 -newkey rsa:4096 -nodes -sha256 -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem -days 3650 -subj "/CN=<$PUBLIC_IP_ADDRESS>"
:!: Расположение tmp
    http {
      server {
        (...)
        client_body_temp_path /deployments/nginx/tmp;
        proxy_temp_path /deployments/nginx/tmp;
        fastcgi_temp_path /deployments/nginx/tmp;
        uwsgi_temp_path /deployments/nginx/tmp;
        scgi_temp_path /deployments/nginx/tmp;
      }
    }
:!:
 
linux/nginx.txt · Последнее изменение: 2024/12/29 06:31 — admin