Эффективное использование ресурсов, отзывчив под нагрузкой.
Используется как веб так и прокси сервер.
Спроектирован на базе асинхронных неблокирующих 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 ~* ^.+.(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.
Далее, достаточно только указать в виртуальном хосте 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 как обычно, только указываем ему нестандартный порт, например 8080.
Далее в настройках виртуального хоста настраиваем Location.
Пример: Перенаправление всего динамического контента, тут 2 блока Location:
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 и пр.
Конфиг содержит древовидную структуру, определен наборами фигурных скобок, эти области называются контекстами. Контексты вкладываются друг в друга, заданные директивы наследуют вложенными контекстами, могут переопределяться
Main
Контекст Main базовый, глобальный, по умолчанию присутствует всегда, директива вне контекстов, содержится в контексте main
Events
Находится в main, определяет глобальные параметры, влияющие на то как Nginx обрабатывает соединения. В конфете может быть только один контекст Events
Как правило метод для обработки соединения выбирается автоматически, платформа выбирает наиболее эффективный из доступных
Http
Содержит все директивы и другие контексты, необходимые для обработки соединений HTTP или HTTPS
Так же является дочерним от main, одноранговые с events, не вкладываются друг в друга
Содержит значения по умолчанию для каждого виртуального сервера, определенного внутри
Server
Обычно объявляется внутри http, может быть объявлен несколько раз. Виртуальный хост, набор параметров для обработки запросов, разные хосты для разных запросов например
Главные директивы для выбора вирт хоста:
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
Настройка журналов указана в основном конфиге /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
Третий параметр указывает уровень протоколирования (каждый уровень включает в себя все нижестоящие):
worker_processes -
worker_connections -
worker_cpu_affinity -
-
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>"
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; } }