Руководство для начинающих
В этом руководстве даётся начальное введение в nginx и описываются
некоторые простые задачи, которые могут быть решены с его помощью.
Предполагается, что nginx уже установлен на компьютере читателя.
Если нет, см. Установка nginx.
В этом руководстве описывается, как запустить и остановить nginx
и перезагрузить его конфигурацию,
объясняется, как устроен конфигурационный файл, и описывается,
как настроить nginx для раздачи статического содержимого, как
настроить прокси-сервер на nginx, и как связать nginx с приложением
FastCGI.
У nginx есть один главный и несколько рабочих процессов.
Основная задача главного процесса — чтение и проверка конфигурации
и управление рабочими процессами.
Рабочие процессы выполняют фактическую обработку запросов.
nginx использует
модель, основанную на событиях, и зависящие от операционной системы
механизмы для эффективного распределения запросов между рабочими процессами.
Количество рабочих процессов задаётся в конфигурационном файле и
может быть фиксированным для данной конфигурации или автоматически
устанавливаться равным числу доступных процессорных ядер (см.
worker_processes).
Как работают nginx и его модули, определяется в конфигурационном файле.
По умолчанию, конфигурационный файл называется nginx.conf
и расположен в каталоге
/usr/local/nginx/conf
,
/etc/nginx
или
/usr/local/etc/nginx
.
Запуск, остановка, перезагрузка конфигурации
Чтобы запустить nginx, нужно выполнить исполняемый файл.
Когда nginx запущен, им можно управлять, вызывая исполняемый файл с
параметром -s
.
Используйте следующий синтаксис:
nginx -s сигнал
Где сигнал может быть одним из нижеследующих:
-
stop
— быстрое завершение -
quit
— плавное завершение -
reload
— перезагрузка конфигурационного файла -
reopen
— переоткрытие лог-файлов
Например, чтобы остановить процессы nginx с ожиданием окончания
обслуживания текущих запросов рабочими процессами, можно выполнить
следующую команду:
nginx -s quit
Команда должна быть выполнена под тем же
пользователем, под которым был запущен nginx.
Изменения, сделанные в конфигурационном файле,
не будут применены, пока команда перезагрузить конфигурацию не будет
вручную отправлена nginx’у или он не будет перезапущен.
Для перезагрузки конфигурации выполните:
nginx -s reload
Получив сигнал, главный процесс проверяет правильность синтаксиса нового
конфигурационного файла и пытается применить конфигурацию, содержащуюся
в нём.
Если это ему удаётся, главный процесс запускает новые рабочие процессы
и отправляет сообщения старым рабочим процессам с требованием завершиться.
В противном случае, главный процесс откатывает изменения и продолжает
работать со старой конфигурацией.
Старые рабочие процессы, получив команду завершиться,
прекращают принимать новые запросы и продолжают обслуживать текущие запросы
до тех пор, пока все такие запросы не будут обслужены.
После этого старые рабочие процессы завершаются.
Посылать сигналы процессам nginx можно также средствами Unix,
такими как утилита kill
.
В этом случае сигнал отправляется напрямую процессу с данным ID.
ID главного процесса nginx записывается по умолчанию в файл
nginx.pid
в каталоге
/usr/local/nginx/logs
или
/var/run
.
Например, если ID главного процесса равен 1628, для отправки сигнала QUIT,
который приведёт к плавному завершению nginx, нужно выполнить:
kill -s QUIT 1628
Для просмотра списка всех запущенных процессов nginx может быть использована
утилита ps
, например, следующим образом:
ps -ax | grep nginx
Дополнительную информацию об отправке сигналов процессам nginx
можно найти в Управление nginx.
Структура конфигурационного файла
nginx состоит из модулей, которые настраиваются директивами, указанными
в конфигурационном файле.
Директивы делятся на простые и блочные.
Простая директива состоит из имени и параметров, разделённых пробелами,
и оканчивается точкой с запятой (;
).
Блочная директива устроена так же, как и простая директива, но
вместо точки с запятой после имени и параметров следует набор дополнительных
инструкций, помещённых внутри фигурных скобок
({
и }
).
Если у блочной директивы внутри фигурных скобок можно задавать другие
директивы, то она называется контекстом (примеры:
events,
http,
server
и
location).
Директивы, помещённые в конфигурационном файле вне любого контекста,
считаются находящимися в контексте
main.
Директивы events
и http
располагаются в контексте main
, server
—
в http
, а location
— в
server
.
Часть строки после символа #
считается комментарием.
Раздача статического содержимого
Одна из важных задач конфигурации nginx — раздача
файлов, таких как изображения или статические HTML-страницы.
Рассмотрим пример, в котором в зависимости от запроса файлы будут
раздаваться из разных локальных каталогов: /data/www
,
который содержит HTML-файлы, и /data/images
,
содержащий файлы с изображениями.
Для этого потребуется отредактировать конфигурационный файл и настроить
блок
server
внутри блока http
с двумя блоками location.
Во-первых, создайте каталог /data/www
и положите в него файл
index.html
с любым текстовым содержанием, а также
создайте каталог /data/images
и положите в него несколько
файлов с изображениями.
Далее, откройте конфигурационный файл.
Конфигурационный файл по умолчанию уже включает в себя несколько
примеров блока server
, большей частью закомментированных.
Для нашей текущей задачи лучше закомментировать все такие блоки и
добавить новый блок server
:
http { server { } }
В общем случае конфигурационный файл может содержать несколько блоков
server
,
различаемых по портам, на
которых они
слушают,
и по
имени сервера.
Определив, какой server
будет обрабатывать запрос,
nginx сравнивает URI, указанный в заголовке запроса, с параметрами директив
location
, определённых внутри блока
server
.
В блок server
добавьте блок location
следующего вида:
location / { root /data/www; }
Этот блок location
задаёт “/
”
в качестве префикса, который сравнивается с URI из запроса.
Для подходящих запросов добавлением URI к пути, указанному в директиве
root,
то есть, в данном случае, к /data/www
, получается
путь к запрашиваемому файлу в локальной файловой системе.
Если есть совпадение с несколькими блоками location
,
nginx выбирает блок с самым длинным префиксом.
В блоке location
выше указан самый короткий префикс,
длины один,
и поэтому этот блок будет использован, только если не будет совпадения
ни с одним из остальных блоков location
.
Далее, добавьте второй блок location
:
location /images/ { root /data; }
Он будет давать совпадение с запросами, начинающимися с
/images/
(location /
для них тоже подходит, но указанный там префикс
короче).
Итоговая конфигурация блока server
должна выглядеть
следующим образом:
server { location / { root /data/www; } location /images/ { root /data; } }
Это уже работающая конфигурация сервера, слушающего на стандартном порту 80
и доступного на локальном компьютере по адресу
http://localhost/
.
В ответ на запросы, URI которых начинаются с /images/
,
сервер будет отправлять файлы из каталога /data/images
.
Например, на запрос
http://localhost/images/example.png
nginx отправит
в ответ файл /data/images/example.png
.
Если же этот файл не существует, nginx отправит ответ, указывающий на
ошибку 404.
Запросы, URI которых не начинаются на /images/
, будут
отображены на каталог /data/www
.
Например, в результате запроса
http://localhost/some/example.html
в ответ будет
отправлен файл /data/www/some/example.html
.
Чтобы применить новую конфигурацию, запустите nginx, если он ещё не запущен,
или отправьте сигнал reload
главному процессу nginx,
выполнив:
nginx -s reload
В случае если что-то работает не как ожидалось, можно попытаться выяснить
причину с помощью файловaccess.log
иerror.log
из каталога
/usr/local/nginx/logs
или
/var/log/nginx
.
Настройка простого прокси-сервера
Одним из частых применений nginx является использование его в качестве
прокси-сервера, то есть сервера, который принимает запросы, перенаправляет их
на проксируемые сервера, получает ответы от них и отправляет их клиенту.
Мы настроим базовый прокси-сервер, который будет обслуживать запросы
изображений из локального каталога и отправлять все остальные запросы на
проксируемый сервер.
В этом примере оба сервера будут работать в рамках одного
экземпляра nginx.
Во-первых, создайте проксируемый сервер, добавив ещё один блок
server
в конфигурационный файл nginx со следующим
содержимым:
server { listen 8080; root /data/up1; location / { } }
Это будет простой сервер, слушающий на порту 8080
(ранее директива listen
не указывалась, потому что
использовался стандартный порт 80) и отображающий все
запросы на каталог /data/up1
в локальной файловой
системе.
Создайте этот каталог и положите в него файл index.html
.
Обратите внимание, что директива root
помещена в контекст
server
.
Такая директива root
будет использована, когда директива
location
, выбранная для выполнения запроса, не содержит
собственной директивы root
.
Далее, используйте конфигурацию сервера из предыдущего раздела
и видоизмените её, превратив в конфигурацию прокси-сервера.
В первый блок location
добавьте директиву
proxy_pass,
указав протокол, имя и порт проксируемого сервера в качестве параметра
(в нашем случае это http://localhost:8080
):
server { location / { proxy_pass http://localhost:8080; } location /images/ { root /data; } }
Мы изменим второй блок
location
, который на данный момент отображает запросы
с префиксом /images/
на файлы из каталога
/data/images
так, чтобы он подходил для запросов изображений
с типичными расширениями файлов.
Изменённый блок location
выглядит следующим образом:
location ~ .(gif|jpg|png)$ { root /data/images; }
Параметром является регулярное выражение, дающее совпадение со всеми
URI, оканчивающимися на .gif
, .jpg
или
.png
.
Регулярному выражению должен предшествовать символ ~
.
Соответствующие запросы будут отображены на каталог /data/images
.
Когда nginx выбирает блок location
,
который будет обслуживать запрос, то вначале он проверяет
директивы location,
задающие префиксы, запоминая location
с самым
длинным подходящим префиксом, а затем проверяет регулярные выражения.
Если есть совпадение с регулярным выражением, nginx выбирает соответствующий
location
, в противном случае берётся запомненный ранее
location
.
Итоговая конфигурация прокси-сервера выглядит следующим образом:
server { location / { proxy_pass http://localhost:8080/; } location ~ .(gif|jpg|png)$ { root /data/images; } }
Этот сервер будет фильтровать запросы, оканчивающиеся на
.gif
, .jpg
или .png
,
и отображать их на каталог /data/images
(добавлением URI к
параметру директивы root
) и перенаправлять все остальные
запросы на проксируемый сервер, сконфигурированный выше.
Чтобы применить новую конфигурацию, отправьте сигнал reload
nginx’у, как описывалось в предыдущих разделах.
Существует множество
других директив для дальнейшей настройки прокси-соединения.
Настройка проксирования FastCGI
nginx можно использовать для перенаправления запросов на FastCGI-серверы.
На них могут исполняться приложения, созданные с использованием
разнообразных фреймворков и языков программирования, например, PHP.
Базовая конфигурация nginx для работы с проксируемым FastCGI-сервером
включает в себя использование директивы
fastcgi_pass
вместо директивы proxy_pass
,
и директив fastcgi_param
для настройки параметров, передаваемых FastCGI-серверу.
Представьте, что FastCGI-сервер доступен по адресу
localhost:9000
.
Взяв за основу конфигурацию прокси-сервера из предыдущего раздела,
замените директиву proxy_pass
на директиву
fastcgi_pass
и измените параметр на
localhost:9000
.
В PHP параметр SCRIPT_FILENAME
используется для
определения имени скрипта, а в параметре QUERY_STRING
передаются параметры запроса.
Получится следующая конфигурация:
server { location / { fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; } location ~ .(gif|jpg|png)$ { root /data/images; } }
Таким образом будет настроен сервер, который будет перенаправлять
все запросы, кроме запросов статических изображений, на проксируемый
сервер, работающий по адресу localhost:9000
,
по протоколу FastCGI.
В данной статье описана установка и настройка высокопроизводительного современного веб-сервера nginx на примере облачной платформы Selectel. Все действия актуальны для ОС Ubuntu 20.04 LTS 64-bit. Nginx — это веб-сервер с открытым исходным кодом, созданный работать под высокой нагрузкой, чаще всего используемый для отдачи статического контента, например, html страниц, медиафайлов, документов, архивов, картинок и т.д. Подготовка […]
В данной статье описана установка и настройка высокопроизводительного современного веб-сервера nginx на примере облачной платформы Selectel. Все действия актуальны для ОС Ubuntu 20.04 LTS 64-bit.
Nginx — это веб-сервер с открытым исходным кодом, созданный работать под высокой нагрузкой, чаще всего используемый для отдачи статического контента, например, html страниц, медиафайлов, документов, архивов, картинок и т.д.
Подготовка сервера
Для начала установим сам сервер. После прохождения регистрации, необходимо войти в панель управления. Далее в меню «Облачная платформа» — «Создать сервер».
Откроется оснастка создания сервера, где необходимо задать понятное для дальнейшей работы имя сервера, в примере это «WebSrv01». Регион и зону можно оставить без изменения. Для выбора операционной системы необходимо нажать кнопку «Выбрать другой источник».
Откроется меню «Выбор источника».
В поле «Операционные системы», выбираем Ubuntu, в левом поле появится список всех доступных образов операционных систем на базе данной ОС, выбираем «Ubuntu 20.04 LTS 64-bit» и нажимаем кнопку «Выбрать».
Перемещаемся вниз по странице. В нашем примере используется только «Локальный диск», флажок установлен, в поле «Сетевые диски» нажимаем кнопку «Удалить диск».
В поле «Сеть», поскольку это наш первый сервер выбираем «Приватная подсеть + 1 плавающий IP», после выбора значение в поле сменится на «Новый плавающий IP адрес».
Необходимо скопировать «Пароль для root», он понадобиться для первоначальной настройки сервера через SSH протокол.
Нажимаем кнопку «Создать», сервер будет доступен примерно через 1 минуту. Переходим в меню «Облачная платформа» — «Серверы».
В списке появится сервер с именем, что задали ранее, его IP адрес, который будем использовать для удаленного подключения, на скриншоте в области с цифрой 3, статус сервера ALIVE, означает готовность сервера. Подключаемся к серверу, используя любой SSH-клиент.
Проведем небольшую первоначальную настройку сервера. Обновим информацию о доступных пакетах из подключенных репозиториев:
apt update
Создадим непривилегированного пользователя, в нашем случае webuser:
adduser webuser
Появится интерактивный диалог, в ходе которого необходимо будет задать пароль (New password), подтвердить его (Retype new password), остальные пункты можно не заполнять, просто нажимая ENTER. В последнем вопросе Is the information correct? [Y/n] необходимо нажать Y и нажать ENTER.
Добавляем пользователя webuser в группу sudo для повышения привилегий:
usermod -aG sudo webuser
Открываем конфигурационный файл SSH-сервера:
nano /etc/ssh/sshd_config
В открывшемся текстовом файле ищем строку #Port 22 и удаляем в начале строки символ комментария #, стандартный номер порта 22 рекомендуется сменить в целях безопасности, пускай это будет 22100. В конечном итоге строка должна выглядеть следующим образом:
Port 22100
Переходим к строке PermitRootLogin yes, меняем значение на no, тем самым запретив вход пользователя root напрямую:
PermitRootLogin no
Находясь в редакторе, нажимаем комбинацию клавиш Ctrl+O, внизу появится строка подтверждения: File Name to Write: /etc/ssh/sshd_config, нажимаем ENTER для сохранения изменений, затем Ctrl+X для выхода из редактора.
После изменений файла конфигурации SSH сервера, необходимо выполнить его перезапуск для того, чтобы изменения вступили в силу:
service sshd restart
Установка nginx
Установка сервера nginx может быть выполнена как непосредственно на машину, так и в виде docker контейнера. У каждого метода есть свои преимущества и недостатки, описание которых выходит за рамки данной статьи. Мы посмотрим оба варианта.
Начнем с непосредственной установки на сервер:
apt install nginx
Будет задан вопрос: Do you want to continue? [Y/n]
Нажимаем Y, затем ENTER.
Дожидаемся окончания процесса установки.
Разрешим автозапуск сервера:
systemctl enable nginx
Проверяем результат:
systemctl is-enabled nginx
Если в ответ получили «enabled», значит nginx успешно добавлен в автозагрузку.
Запуск nginx
Стартуем наш веб-сервер:
service nginx start
Проверяем статус:
service nginx status
Если в статусе присутствует строка Active: active (running), значит сервер работает. Также в этом можно убедиться, набрав в адресной строке браузера IP адрес сервера, будет отображено приветственное сообщение от nginx, которое выглядит так:
Nginx в Docker
Для установки Docker, нужно подготовить систему. Устанавливаем необходимые пакеты:
apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
Будет задан вопрос: Do you want to continue? [Y/n]
Нажимаем Y, затем ENTER.
Добавляем GPG ключ официального репозитория Docker в систему:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
В следующей строке появится надпись OK, добавляем репозиторий Docker:
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
Теперь необходимо обновить информацию о пакетах:
apt update
Проверим, что установка Docker будет происходить из его репозитория:
apt-cache policy docker-ce
В ответ должны получить много строк, среди которых должен присутствовать адрес репозитория, добавленный ранее, в нашем примере это:
https://download.docker.com/linux/ubuntu focal/stable
Ставим сам Docker:
apt install docker-ce
Будет задан вопрос: Do you want to continue? [Y/n]
Нажимаем Y, затем ENTER.
Дожидаемся окончания процесса установки. После docker будет автоматически запущен и добавлен в автозагрузку. Проверим:
systemctl status docker
В выводе команды должна присутствовать строка Active: active (running), значит процесс-демон работает.
systemctl is-enabled docker
В ответе увидели «enabled», значит docker успешно добавлен в автозагрузку. На этом установка Docker завершена, переходим к запуску в контейнере веб-сервера nginx.
Создадим проект и его структуру папок в домашнем каталоге нашего пользователя webuser:
mkdir -p /home/webuser/myproject/www
mkdir -p /home/webuser/myproject/nginx_logs
echo '<html><body>Hello from NGINX in Docker!</body></html>' > /home/webuser/myproject/www/index.html
Устанавливаем и запускаем nginx в Docker одной командой:
docker run --name nginx_myproject -p 8080:80 -v /home/webuser/myproject/www:/usr/share/nginx/html -v /home/webuser/myproject/nginx_logs:/var/log/nginx -d nginx
Docker скачает официальный образ nginx с Docker Hub, сконфигурирует и запустит контейнер.
Здесь:
- nginx_myproject – имя контейнера, создаваемого на базе образа nginx.
- Конструкция –p 8080:80 выполняет проброс портов, с порта 8080 локальной машины на порт 80 контейнера.
- Флаги –v по аналогии с портом – пробрасывают локальную директорию внутрь контейнера, т.е. директория /home/webuser/myproject/www на локальной машине будет доступна в контейнере как /usr/share/nginx/html, и /home/webuser/myproject/nginx_logs в контейнере это /var/log/nginx.
Проверяем, работает ли контейнер:
docker ps
Вывод команды должен быть примерно следующим:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f35d422d233a nginx "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:8080->80/tcp nginx_myproject
Стоит обратить внимание на столбец NAMES, где обнаруживаем имя созданного ранее контейнера nginx_myproject, колонка STATUS, в которой отображается состояние контейнера, в данном случае он работает уже 7 часов. Если набрать в адресной строке браузера IP адрес сервера и через двоеточие порт, используемый контейнером 8080, т.е. конструкцию вида 123.123.123.123:8080, то в ответ получим:
«Hello from NGINX in Docker!»
Мы научились запускать веб-сервер nginx в контейнере!
Проброс портов, папок, а так же многий другой функционал, предоставляемый контейнеризацией, должен быть использован исходя из поставленных задач, разнообразие которых выходит за рамки данной статьи. Дальнейшее описание работы с nginx рассматривается в рамках работы непосредственно на сервере, без контейнеризации.
Иерархия каталогов nginx
Администрирование сервера nginx в основном заключается в настройке и поддержке его файлов конфигурации, которые находятся в папке /etc/nginx. Рассмотрим подробнее:
- /etc/nginx/nginx.conf – главный файл конфигурации nginx.
- /etc/nginx/sites-available – каталог с конфигурациями виртуальных хостов, т.е. каждый файл, находящийся в этом каталоге, содержит информацию о конкретном сайте – его имени, IP адресе, рабочей директории и многое другое.
- /etc/nginx/sites-enabled – в этом каталоге содержаться конфигурации сайтов, обслуживаемых nginx, т.е. активных, как правило, это символические ссылки sites-available конфигураций, что очень удобно для оперативного включения и отключения сайтов.
Настройка nginx
Рассмотрим главный конфигурационный файл nginx — /etc/nginx/nginx.conf. По умолчанию он выглядит следующим образом:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Конфигурационный файл состоит из директив. О них и пойдет речь дальше.
Директивы
Существует два вида директив – простые и блочные. Простая директива состоит из имени и параметров, разделённых пробелами, и в конце строки ставится точкой с запятой (;). Блочная директива устроена так же, как и простая директива, но вместо точки с запятой после имени и параметров следует набор дополнительных инструкций, помещённых внутри фигурных скобок ({ и }). Рассмотрим те, которые пригодятся нам для примера:
- user – пользователь, от имени которого работает nginx, здесь это www-data;
- worker_processes – количество процессов сервера, значение выставляется равным количеству ядер процессора, auto – сервер определит автоматически;
- pid – файл, внутри которого хранится идентификатор запущенного главного процесса (PID);
- include – подключаемый файл или файлы конфигурации;
- events – блок директив, определяющих работу с сетевыми соединениями;
- worker_connections – максимальное количество одновременных соединений;
- http – блок директив http сервера;
- sendfile – метод отправки данных, включаем значением on;
- tcp_nopush и tcp_nodelay – параметры, положительно влияющие на производительность, оставляем значение on;
- keepalive_timeout – время ожидания keepalive соединения до его разрыва со стороны сервера;
- types_hash_max_size – регламентирует максимальный размер хэш таблиц типов;
- default_type – указывает тип MIME ответа по умолчанию;
- ssl_protocols – включает указанные протоколы;
- ssl_prefer_server_ciphers – указывает, что серверное шифрование; предпочтительнее клиентского, при использовании SSLv3 и TLS протоколов;
- access_log – задает путь к файлу лога доступа, при выставлении значения в off, запись в журнал доступа будет отключена;
- error_log – путь к журналу регистрации ошибок;
- gzip – при помощи этой директивы можно включать или отключать сжатие.
Переменные в nginx
В конфигурационных файлах nginx допустимо пользоваться встроенными переменными. Преимущественно это переменные, представляющие собой поля заголовка запроса клиента, такие как $remote_addr, $server_name. Все переменные начинаются со знака $, с полным перечнем можно ознакомиться в документации, на официальном сайте.
Установка и настройка php-fpm
Для работы веб приложений, написанных на языке PHP необходимо установить php-fpm в качестве бэкэнда:
apt install php-fpm php-mysql
Будет задан вопрос: Do you want to continue? [Y/n]
Нажимаем Y, затем ENTER.
После установки сервис будет автоматически запущен и добавлен в автозагрузку. Создаем файл пула для конкретного сайта sampledomain.ru:
touch /etc/php/7.4/fpm/pool.d/sampledomain.ru.conf
nano /etc/php/7.4/fpm/pool.d/sampledomain.ru.conf
Создаем следующую конфигурацию:
[sampledomain.ru]
listen = /var/run/php/sampledomain.ru.sock
listen.mode = 0666
user = webuser
group = webuser
chdir = /home/webuser/www/sampledomain.ru
php_admin_value[upload_tmp_dir] = /home/webuser/tmp
php_admin_value[soap.wsdl_cache_dir] = /home/webuser/tmp
php_admin_value[date.timezone] = Europe/Moscow
php_admin_value[upload_max_filesize] = 100M
php_admin_value[post_max_size] = 100M
php_admin_value[open_basedir] = /home/webuser/www/sampledomain.ru/
php_admin_value[session.save_path] = /home/webuser/tmp
php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source
php_admin_value[cgi.fix_pathinfo] = 0
php_admin_value[apc.cache_by_default] = 0
pm = dynamic
pm.max_children = 7
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
Нажимаем комбинацию клавиш Ctrl+O, внизу появится строка подтверждения: File Name to Write: /etc/php/7.4/fpm/pool.d/sampledomain.ru.conf, нажимаем ENTER для сохранения изменений, затем Ctrl+X для выхода из редактора.
Перезагружаем сервис php-fpm, чтобы он мог перечитать файлы конфигураций:
service php7.4-fpm restart
Проверяем, что сервис перезапустился корректно и наша новая конфигурация sampledomain.ru обслуживается:
service php7.4-fpm status
О том, что сервис запущен, свидетельствует наличие строки Active: active (running), чуть ниже список обслуживаемых конфигураций в виде дерева, где можно увидеть php-fpm: pool sampledomain.ru, значит все работает.
Конфигурация nginx
Структура директорий веб проекта будет размещена в домашней папке пользователя webuser, это облегчит дальнейшую унификацию конфигурационных файлов и масштабируемость. Например, когда возникает необходимость на одном сервере разместить несколько сайтов, у каждого из них свой владелец. В таком случае создается новый пользователь, пусть будет webuser2, аналогично в его папке разворачивается такая же структура каталогов.
У нас имеется главный конфигурационный файл, содержимое которого оставляем неизменным для примера. Создадим файл виртуального хоста:
touch /etc/nginx/sites-available/sampledomain.ru.conf
nano /etc/nginx/sites-available/sampledomain.ru.conf
Заполняем его следующим содержимым:
server
{
listen 80;
server_name sampledomain.ru www.sampledomain.ru;
charset utf-8;
root /home/webuser/www/sampledomain.ru;
index index.php index.html index.htm;
# Static content
location ~* ^.+.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|mp3|bmp|flv|rtf|js|swf|iso)$ {
root /home/webuser/www/sampledomain.ru;
}
location ~ .php$
{
include fastcgi.conf;
fastcgi_intercept_errors on;
try_files $uri =404;
fastcgi_pass unix://var/run/php/sampledomain.ru.sock;
}
location / {
try_files $uri $uri/ /index.php?q=$uri$args;
}
}
Нажимаем комбинацию клавиш Ctrl+O, внизу появится строка подтверждения: File Name to Write: /etc/nginx/sites-available/sampledomain.ru.conf, нажимаем ENTER для сохранения изменений, затем Ctrl+X для выхода из редактора.
Создаем символическую ссылку на данный виртуальный хост из директории /etc/nginx/sites-available в директорию /etc/nginx/sites-enabled, чтобы nginx его обслуживал:
ln -s /etc/nginx/sites-available/sampledomain.ru.conf /etc/nginx/sites-enabled/
Необходимо создать структуру каталогов веб проекта:
mkdir -p /home/webuser/www/sampledomain.ru
mkdir -p /home/webuser/tmp
Создаем файл для тестирования работы связки nginx и php-fpm:
echo "<?php phpinfo(); ?>" > /home/webuser/www/sampledomain.ru/index.php
Задаем владельца каталогов и находящихся внутри файлов:
chown -R webuser:webuser /home/webuser/www/
chown -R webuser:webuser /home/webuser/tmp/
Добавляем пользователя www-data в группу webuser:
usermod -aG webuser www-data
Конфиги написаны, директории созданы, перезапускаем nginx для того, чтобы он перечитал файлы конфигураций:
service nginx restart
Переходим в браузере по адресу http://sampledomain.ru и должны увидеть такую картину:
Все настроили правильно.
Команды nginx
Рассмотрим несколько команд, которые полезно знать администратору. После внесения изменений в конфигурационные файлы сервера, рекомендуется провести их синтаксический контроль:
nginx -t
Если все хорошо, в результате получим сообщение:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
В случае обнаружения ошибок, сервер уведомит об этом. Чтобы узнать используемую версию сервера, нужно ввести:
nginx –v
Можно получить расширенную информацию об nginx – его версию, параметры конфигурации сборки:
nginx –V
Когда существует необходимость оперативно, но аккуратно перезапустить веб-сервер, чтобы пользователи на данный момент, работающие с ним, не потеряли соединение, но в то же время, вновь подключившиеся уже работали с учетом последних изменений конфигурации. В таком случае, вместо restart необходимо использовать команду reload:
service nginx reload
Настройка SSL сертификата
Получение SSL сертификата необходимо для использования протокола HTTPS. Данный протокол защищает соединение между сервером и клиентом, особенно критично для чувствительных данных, таких как логины, пароли, данные по банковским картам, переписка и так далее. Последние несколько лет поисковые системы наиболее лояльны к сайтам, использующих данный протокол, есть прекрасная возможность получить ssl сертификат бесплатно от Let’s Encrypt, устанавливаем его клиент certbot из официального репозитория:
apt install certbot python3-certbot-nginx
Будет задан вопрос: Do you want to continue? [Y/n]
Нажимаем Y, затем ENTER.
Запрашиваем сертификат у Certbot:
certbot certonly --agree-tos -m mymail@yandex.ru --webroot -w /home/webuser/www/sampledomain.ru/ -d sampledomain.ru
Появится вопрос о передаче вашего адреса электронной почты компании партнеру: (Y)es/(N)o:
Жмем Y, потом ENTER.
Сертификат успешно получен, если появилось сообщение:
IMPORTANT NOTES:
— Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/sampledomain.ru/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/sampledomain.ru/privkey.pem
Your cert will expire on 2021-05-27. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
— Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
— If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Сертификат действителен 90 дней. Теперь необходимо позаботиться об автоматическом продлении сертификатов, открываем файл:
nano /etc/cron.d/certbot
Приводим его к следующему виду:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --renew-hook "systemctl reload nginx"
Нажимаем комбинацию клавиш Ctrl+O, внизу появится строка подтверждения: File Name to Write: /etc/cron.d/certbot, нажимаем ENTER для сохранения изменений, затем Ctrl+X для выхода из редактора.
Дважды в день будет происходить проверка необходимости обновления сертификатов на сервере, если какому-либо осталось 30 дней и меньше до истечения срока действия – он будет обновлен, а nginx перезагружен.
Протестируем процесс обновления без внесения изменений:
certbot renew --dry-run
Ждем около полминуты, на экран будет выведен подробный отчет. Если присутствует строка Congratulations, all renewals succeeded – значит все настроено правильно. Если когда-либо в процессе обновления произойдет сбой – Let’s Encrypt уведомит о приближающимся конце срока действия сертификата по электронной почте, указанной при первом запросе.
Редирект с http на https
После получения сертификата необходимо прописать директивы в файл конфигурации виртуального хоста, отвечающие за поддержку SSL. Сразу же реализуем перенаправление всех запросов, приходящих на 80-й порт к порту 443, т.е. с http протокола на https. Открываем файл:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Приводим его к следующему виду:
server {
listen 80;
server_name sampledomain.ru www.sampledomain.ru;
root /home/webuser/www/sampledomain.ru;
return 301 https://sampledomain.ru$request_uri;
}
server
{
listen 443 ssl;
server_name sampledomain.ru www.sampledomain.ru;
# SSL support
ssl_certificate /etc/letsencrypt/live/sampledomain.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sampledomain.ru/privkey.pem;
charset utf-8;
root /home/webuser/www/sampledomain.ru;
index index.php index.html index.htm;
# Static content
location ~* ^.+.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|mp3|bmp|flv|rtf|js|swf|iso)$ {
root /home/webuser/www/sampledomain.ru;
}
location ~ .php$
{
include fastcgi.conf;
fastcgi_intercept_errors on;
try_files $uri =404;
fastcgi_pass unix://var/run/php/sampledomain.ru.sock;
}
location / {
try_files $uri $uri/ /index.php?q=$uri$args;
}
}
Нажимаем комбинацию клавиш Ctrl+O, внизу появится строка подтверждения: File Name to Write: /etc/nginx/sites-available/sampledomain.ru.conf, нажимаем ENTER для сохранения изменений, затем Ctrl+X для выхода из редактора.
Перезапускаем веб-сервер:
service nginx restart
Теперь в браузере при попытке перехода по адресу http://sampledomain.ru будет выполнено перенаправление на https://sampledomain.ru
Кэширование в nginx
Основная задача кэширования – это минимизация времени доступа к данным. Nginx умеет работать с несколькими видами кэширования: на стороне сервера, на стороне клиента. Серверное кэширование может иметь самую разнообразную конфигурацию, в зависимости от архитектуры проекта. Поэтому в нашем частном случае рассмотрим кэширование на стороне клиента (браузера) для статического контента.
Открываем файл нашего тестового виртуального хоста:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Находим location, указывающий на отдачу статического контента и добавляем директиву expires:
# Static content
location ~* ^.+.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|mp3|bmp|flv|rtf|js|swf|iso)$ {
root /home/webuser/www/sampledomain.ru;
expires 1d;
}
Как обычно сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. В данном случае файлы, расширения которых соответствуют приведенным выше, будут храниться в браузере клиента, только после истечения суток – они будут запрошены повторно.
Кэширование позволяет значительно уменьшить время доставки контента и его объем, снизить нагрузку на сервер, а значит, ваш сайт сможет работать значительно быстрее и принять больше посетителей.
Мониторинг nginx
В nginx существует стандартная возможность мониторинга работы сервера, выясним доступность модуля в нашей сборке:
nginx -V 2>&1 | grep -o with-http_stub_status_module
Если в ответ получили with-http_stub_status_module – модуль доступен. Рассмотрим включение мониторинга на примере виртуального хоста, открываем файл:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Добавляем location /nginx_status, в итоге файл выглядит следующим образом:
server {
listen 80;
server_name sampledomain.ru www.sampledomain.ru;
root /home/webuser/www/sampledomain.ru;
return 301 https://sampledomain.ru$request_uri;
}
server
{
listen 443 ssl;
server_name sampledomain.ru www.sampledomain.ru;
# SSL support
ssl_certificate /etc/letsencrypt/live/sampledomain.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sampledomain.ru/privkey.pem;
charset utf-8;
root /home/webuser/www/sampledomain.ru;
index index.php index.html index.htm;
# Static content
location ~* ^.+.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|mp3|bmp|flv|rtf|js|swf|iso)$ {
root /home/webuser/www/sampledomain.ru;
expires 1d;
}
location ~ .php$
{
include fastcgi.conf;
fastcgi_intercept_errors on;
try_files $uri =404;
fastcgi_pass unix://var/run/php/sampledomain.ru.sock;
}
location / {
try_files $uri $uri/ /index.php?q=$uri$args;
}
location /nginx_status {
stub_status on;
access_log off;
}
}
Сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. Перезапускаем веб-сервер:
service nginx restart
В браузере при переходе по адресу sampledomain.ru/nginx_status будет представлена статистика работы сервера:
Active connections: 2
server accepts handled requests
797 797 334
Reading: 0 Writing: 1 Waiting: 1
- Active connections – текущее количество клиентских соединений;
- accepts – принятые соединения;
- handled – обработанные, обычно равно количеству принятых;
- requests – количество клиентских запросов;
- Reading – текущее количество соединений, для которых сервер читает заголовок запроса;
- Writing – текущее количество соединений, для которых сервер отправляет ответ клиенту;
- Waiting – текущее количество простаивающих соединений, для которых сервер ожидает запроса.
Также статистику можно получить из командной строки:
curl https://sampledomain.ru/nginx_status
Не рекомендуется статистику выставлять на всеобщее обозрение, ниже рассмотрим вопросы безопасности и ограничений доступа.
Проксирование запросов
Nginx умеет проксировать запросы на другие сервера, понадобиться это для масштабирования и защиты back-end серверов. В качестве примера, запустим back-end сервер apache в контейнере:
docker run --name backend_apache -p 8081:80 -d httpd
Дожидаемся процесса скачивания образа, контейнер запуститься автоматически, убеждаемся, что среди запущенных контейнеров присутствует backend_apache:
docker ps
Открываем файл виртуального хоста:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Изменим блок location / так, чтобы при обращении к sampledomain.ru запрос был передан веб-серверу apache, работающему в контейнере:
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
Сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. Перезапускаем веб-сервер:
service nginx restart
Директива proxy_pass задает протокол, адрес и порт проксируемого ресурса, proxy_set_header директивы настраивают заголовки запросов, передают проксируемому ресурсу информацию о соединении.
Если перейти в браузере по адресу http://sampledomain.ru, можно увидеть «It works!», отдаваемый ранее созданным контейнером с apache.
Балансировка нагрузки
Для улучшения отказоустойчивости, масштабируемости, уменьшения время отклика, распределения полезной нагрузки придумали балансировщики нагрузок. На примере посмотрим, как приспособить для этого nginx.
Открываем файл виртуального хоста:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Над блоком server добавляем следующее:
upstream backends {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
Также вносим изменения в блок location /:
location / {
proxy_pass http://backends;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
Сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. Перезапускаем веб-сервер:
service nginx restart
Директива upstream перечисляет все back-end сервера, между которыми следует распределить нагрузку. В блоке location / изменился параметр директивы proxy_pass на http://backends, где backends – имя, которое присвоили группе серверов директивы upstream.
Ранее мы запустили два контейнера: первый с nginx на порту 8080, второй с apache на порту 8081. Теперь перейдя в браузере по ссылке http://sampledomain.ru и несколько раз обновляя страницу можно наблюдать чередование ответов «It works!» и «Hello from NGINX in Docker!», значит балансировка работает.
Существует несколько методов балансировки:
round-robin – используется по умолчанию, нагрузка распределяется равномерно между серверами с учетом веса.
least_conn – запросы поступают к менее загруженным серверам.
Пример использования:
upstream backends {
least_conn;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
ip_hash — запросы распределяются по серверам на основе IP-адресов клиентов, т.е. запросы одного и того же клиента будут всегда передаваться на один и тот же сервер, пример:
upstream backends {
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
Если в группе серверов некоторые производительнее остальных, то следует воспользоваться механизмом весов. Это условная единица, которая позволяет направлять наибольшую нагрузку на одни сервера и ограждать от нее другие.
Разберем на примере:
upstream backends {
server 127.0.0.1:8080 weight=5;
server 127.0.0.1:8081 weight=2;
}
В данной конфигурации, из 7 запросов, 5 будет обработано сервером 127.0.0.1:8080, а 2 машиной 127.0.0.1:8081
Безопасность nginx
В данном разделе мы рассмотрим общие принципы обеспечения безопасности как сервера в целом, так и отдельных его ресурсов.
HTTP аутентификация
Для защиты определенных ресурсов сайта, например, таких как панель администратора, статистика, каталоги с файлами для внутреннего использования, иногда может потребоваться дополнительная мера – от пользователя потребуется ввести логин и пароль.
Установим утилиту для генерации хешированных паролей:
apt install apache2-utils
Будет задан вопрос: Do you want to continue? [Y/n]
Нажимаем Y, затем ENTER.
Теперь создадим файл, в котором будет содержаться список логинов и паролей пользователей:
touch /etc/nginx/conf.d/htpasswd
Добавим пользователя user:
htpasswd /etc/nginx/conf.d/htpasswd user
Будет предложено ввести пароль, вводимые символы не отображаются, это нормально, после нажать ENTER:
New password:
Ввести повторно тот же пароль:
Re-type new password:
Появление ответа Adding password for user user означает, что все сделано верно. Точно так же можно добавить других пользователей. Чтобы сменить пароль пользователя user – нужно повторно ввести предыдущую команду, данные в файле будут обновлены.
В примере будем защищать доступ к нашему виртуальному хосту, а конкретно к статистике работы сервера, открываем файл конфигурации:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Редактируем location /nginx_status следующим образом:
location /nginx_status {
stub_status on;
access_log off;
auth_basic "Enter your credential data: ";
auth_basic_user_file /etc/nginx/conf.d/htpasswd;
}
Сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. Перезапускаем nginx:
service nginx restart
Теперь при переходе в раздел просмотра статистики sampledomain.ru/nginx_status необходимо будет сначала ввести логин и пароль для доступа к разделу, в противном случае сервер выдаст ошибку: 401 Authorization Required.
Авторизацию по паролю рекомендуется использовать исключительно для служебных целей и совместно с протоколом https, иначе данные передаются в открытом виде.
Ограничение доступа по IP адресу
В качестве примера отредактируем тренировочный виртуальный хост:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Рассмотрим блок location /nginx_status, приведем его к виду:
location /nginx_status {
stub_status on;
access_log off;
allow 192.168.0.0/24;
allow 192.168.1.1;
deny all;
}
Сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. Перезапускаем nginx:
service nginx restart
В данном примере разрешен доступ для компьютеров из сети 192.168.0.0 с маской подсети 255.255.255.0 (/24) и хоста с адресом 192.168.1.1. Для всех остальных доступ закрыт.
Комбинация ограничений
Рассмотрим ситуацию, когда имеется предприятие, с внутренней сетью 192.168.0.0/24, и сотрудники из нее должны беспрепятственно попадать в нужный раздел, но в то же время необходимо предоставить доступ снаружи, используя авторизацию по логину и паролю. Тогда location /nginx_status принимает следующий вид:
location /nginx_status {
stub_status on;
access_log off;
satisfy any;
allow 192.168.0.0/24;
deny all;
auth_basic "Enter your credential data: ";
auth_basic_user_file /etc/nginx/conf.d/htpasswd;
}
Сфокусируем внимание на директиве satisfy. В данном случае она имеет параметр any, что означает предоставление доступа при выполнении хотя бы одного из условий. При смене параметра на all – сотрудникам предприятия будет разрешен доступ только из внутренней сети с аутентификацией по логину и паролю.
Предотвращение DDoS атак
DDoS — это распределенная атака отказа в обслуживании, происходит с нескольких IP адресов, направлена на ухудшение или полное отсутствие доступности сервера за счёт огромного количества запросов. Чаще всего, это происки недобросовестных конкурентов, реже из хулиганских побуждений. В nginx предусмотрен механизм, позволяющий, если не полностью подавить атаку, то как минимум смягчить ее влияние на работу системы.
Возможно ограничить скорость приема входящих запросов в единицу времени с одного IP адреса. Так же можно ограничить количество одновременных подключений с одного IP адреса. Обе техники посмотрим на примере файла конфигурации виртуального хоста, открываем:
nano /etc/nginx/sites-available/sampledomain.ru.conf
Доводим до следующего состояния:
limit_req_zone $binary_remote_addr zone=one:10m rate=90r/m;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
listen 80;
server_name sampledomain.ru www.sampledomain.ru;
root /home/webuser/www/sampledomain.ru;
return 301 https://sampledomain.ru$request_uri;
}
server
{
listen 443 ssl;
server_name sampledomain.ru www.sampledomain.ru;
# SSL support
ssl_certificate /etc/letsencrypt/live/sampledomain.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sampledomain.ru/privkey.pem;
charset utf-8;
root /home/webuser/www/sampledomain.ru;
index index.php index.html index.htm;
# Static content
location ~* ^.+.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|mp3|bmp|flv|rtf|js|swf|iso)$ {
root /home/webuser/www/sampledomain.ru;
expires 1d;
}
location ~ .php$
{
limit_req zone=one;
limit_conn addr 10;
include fastcgi.conf;
fastcgi_intercept_errors on;
try_files $uri =404;
fastcgi_pass unix://var/run/php/sampledomain.ru.sock;
}
location / {
try_files $uri $uri/ /index.php?q=$uri$args;
}
location /nginx_status {
stub_status on;
access_log off;
satisfy any;
allow 192.168.0.0/24;
deny all;
auth_basic "Enter your credential data: ";
auth_basic_user_file /etc/nginx/conf.d/htpasswd;
}
}
Сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. Перезапускаем nginx:
service nginx restart
- limit_req_zone – директива, хранящая состояние ключа, в нашем случае это адрес клиента $binary_remote_addr, в зоне one, размером 10 Мб, со скоростью обработки запросов не превышающая 90 в минуту.
- limit_req – директива в location ~ .php$, ссылающаяся на зону разделяемой памяти.
- limit_conn_zone – директива, хранящая состояние ключа, в нашем случае это адрес клиента $binary_remote_addr, в зоне addr, размером 10Мб.
- limit_conn — директива в location ~ .php$, ссылающаяся на зону разделяемой памяти, задающая лимит на количество соединений с одного IP адреса, в данном случае 10.
Следует внимательно отнестись к настройке подобных значений, поскольку полезные и оптимальные значения для одного проекта, могут быть неприемлемы в другом.
Ошибки nginx
В работе любых систем, а особенно на этапе пуско-наладочных работ, возникают ошибки, в данном разделе рассмотрим наиболее распространенные и методы их устранения.
502 bad gateway
Эта ошибка говорит о том, что back-end, обрабатывающий запрос от nginx – перестал отвечать. Произойти это могло также по нескольким причинам. Во-первых, back-end мог упасть полностью и для восстановления его необходимо запустить. Во-вторых, если nginx и back-end сервер находятся на физически разных машинах – между ними могла банально пропасть связь. Для проверки необходимо воспользоваться командой ping. Так же, возможно, часть процессов php-fpm перегружены или не хватает их количества для обслуживания всех клиентов, тогда эта ошибка будет иметь «плавающий» характер. Открываем файл:
nano /etc/php/7.4/fpm/pool.d/sampledomain.ru.conf
Если действительно проблема в нехватке процессов — стоит «покрутить» следующие настройки:
pm = dynamic
pm.max_children = 7
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
504 Gateway Time-out
Одна из причин возникновения ошибки – превышение времени ожидания ответа от сервера, например от php-fpm. Такое случается, когда скрипты php долго выполняются или зависли. Если обработка запроса требует большего времени – увеличим время ожидания на передачу запроса fastcgi_send_timeout и получение ответа fastcgi_read_timeout, редактируем блок location ~ .php$:
location ~ .php$
{
limit_req zone=one;
limit_conn addr 2;
include fastcgi.conf;
fastcgi_intercept_errors on;
try_files $uri =404;
fastcgi_pass unix://var/run/php/sampledomain.ru.sock;
fastcgi_send_timeout 120;
fastcgi_read_timeout 120;
}
Сохраняем результат Ctrl+O, подтверждаем нажатием ENTER, выходим из редактора Ctrl+X. Перезапускаем nginx:
service nginx restart
413 Request Entity Too Large
Ошибка возникает, когда на сервер загружается файл, превышающий значение директивы client_max_body_size, по умолчанию – 1 Мб. Добавим в блок server:
server {
### остальные директивы
client_max_body_size 50m;
### остальные директивы
}
В примере максимально допустимый размер тела запроса клиента увеличен до 50 Мб. При повторном возникновении ошибки – снова увеличить. Не забываем сохраняться и после изменений – перезапускать nginx:
service nginx restart
Искать причины возникновения тех или иных ошибок правильнее всего в логах, которые находятся в папке /var/log/nginx/. Однако, у начинающего администратора возникают сложности с интерпретацией, содержащейся в них информации.
В таком случае можно посоветовать определить строку, где содержится сообщение об ошибке, выделить текст сообщения и вбить его в поисковую систему. Как правило, в сети найдется огромное количество ресурсов с описанием решения тех или иных сложностей.
In this article I will tell you where Nginx server is installed and how to find out it’s configuration file after installation. It is very useful when you jump into an existing Nginx server and just want to find and modify it’s configuration files.
1. How To Find Nginx Install Path And Configuration Files.
There are several commands that you can use to find Nginx installation path and it’s configuration files path.
- Open a terminal and run
whereis nginx
command to return where the Nginx binary file is. But the Nginx bin directory path should exist in PATH system environment.$ whereis nginx nginx: /usr/bin/nginx /usr/local/nginx $ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
- If there are multiple Nginx binary file path records in above command result, you can run
which nginx
to show the currently used Nginx binary file path.$ which nginx /usr/bin/nginx
- You can run command
ls -al /usr/bin/nginx
to get the Nginx binary file linked real Nginx server binary file as below.$ ls -al /usr/bin/nginx lrwxrwxrwx. 1 root root 28 Dec 21 08:30 /usr/bin/nginx -> /www/server/nginx/sbin/nginx
- If the Nginx binary file path do not exist in environment variable PATH value, you can run
ps -ef | grep nginx
command to list currently running Nginx process information.$ ps -ef|grep nginx root 1412 1 0 Dec21 ? 00:00:00 nginx: master process /www/server/nginx/sbin/nginx -c /www/server/nginx/conf/nginx.conf
- From above
ps -ef|grep nginx
command, we can see Nginx binary file is located at/www/server/nginx/sbin/nginx
, and Nginx configuration file is located at/www/server/nginx/conf/nginx.conf
. - If the Nginx server is running now, you can also run command
nginx -t
to get and test the Nginx server configuration file.$ nginx -t nginx: the configuration file /www/server/nginx/conf/nginx.conf syntax is ok nginx: configuration file /www/server/nginx/conf/nginx.conf test is successful
2. Some Nginx Useful Commands.
- Command
nginx -V/v
can get current executing Nginx server version. The -V will return more detail version information.$ nginx -V nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) built with OpenSSL 1.1.1i 8 Dec 2020 .............. $ nginx -v nginx version: nginx/1.18.0
- Start / stop / restart / reload Nginx server.
$ sudo systemctl start nginx $ sudo systemctl stop nginx $ sudo systemctl restart nginx $ sudo systemctl reload nginx
- Get Nginx running status.
$ sudo systemctl status nginx
- Enable / Disable launch Nginx server when Linux server is started.
$ sudo systemctl enable nginx $ sudo systemctl disable nginx
- Display Nginx command line help information.
$ sudo systemctl -h nginx systemctl [OPTIONS...] {COMMAND} ... Query or send control commands to the systemd manager. -h --help Show this help --version Show package version --system Connect to system manager -H --host=[[email protected]]HOST Operate on remote host -M --machine=CONTAINER Operate on local container -t --type=TYPE List units of a particular type --state=STATE List units with particular LOAD or SUB or ACTIVE state ......... .........
Since its introduction more than 15 years ago, NGINX has gained steadily in popularity and is now the most popular web server in the world, powering more than 350 million websites. In this case we think it’s smart to follow the crowd and use NGINX for all your web‑serving needs, and additionally to take advantage of its capabilities as a reverse proxy, content cache, load balancer, API gateway, and more.
This blog post guides you in getting NGINX up and running on Ubuntu 20.04 on Amazon Web Services (AWS) in an easy-to-use setup that doesn’t affect the settings on your personal computer. It covers both NGINX and NGINX Plus, the commercially supported version with additional enterprise‑grade features.
Once you complete the steps given here, you may want to continue with NGINX Core training (instructor‑led or on‑demand), a full‑day course where you’ll learn how to configure, administer, and manage NGINX. The course also readies you for our other instructor‑led and self‑paced courses on advanced topics.
The tutorial includes instructions for these tasks:
- Setting Up AWS
- Installing NGINX Software
- Opening Your Web Page
- Setting Up Sample Files
- Serving Pages and Images
- Setting Up a Proxy Server
Accessing a Terminal
For this tutorial, you need a terminal to connect to your Amazon Elastic Compute Cloud (EC2) instance. Macs have a built‑in terminal, but Windows users need to download PuTTY or an equivalent tool. If you prefer to use your own local terminal to set up NGINX or NGINX Plus and serve web content, feel free to skip to Setting up AWS.
Accessing a Terminal on MacOS
On Macs, you can use the built‑in terminal
tool to do everything in this tutorial.
-
Click the magnifying glass icon at the right end of the top bar on the screen.
-
Type
terminal
in the pop‑up box and press Enter. A separate terminal window opens.
Accessing a Terminal on Windows
Windows doesn’t come with a built‑in terminal, so you need to download one from the Internet. Along with AWS, we recommend PuTTY, an ssh
client used throughout the world.
-
Access the PUTTY download page.
-
Download and install the file in a location of your choice, then open it. You can’t access the actual terminal until you finish the steps in the Setting up AWS, however.
In this tutorial we assume that you have an Amazon Virtual Private Cloud (VPC) and can simply use the default VPC configuration that is created with most accounts. In this section, you set up your AWS deployment by creating an EC2 instance and connecting to it.
Note: The following procedure and screenshots for creating an EC2 instance were verified at the time of writing, but are subject to change by AWS. Adapt the instructions as necessary.
-
On the AWS home page, sign in to the (AWS Management) Console, or first create a new account if necessary.
-
Click Services in the Console title bar, then EC2 in the Compute section.
-
Click the Launch Instance button on the EC2 Dashboard page that opens.
-
On the Step 1 page, click the Select button in the Ubuntu Server 20.04 LTS (HVM), SSD Volume Type row, and keep the default 64-bit (x86) architecture selection.
-
On the Step 2 page, select the t2.micro instance type, which as of this writing is marked Free tier eligible and selected by default. Click the Next: Configure Instance Details button.
-
On the Step 3 page, make sure the VPC you want to use is selected in the Network field, and that the Auto-assign Public IP field is set either to the default Use Subnet setting (Enable) or to Enable. Leave the rest of the settings at their defaults.
-
Click 6. Configure Security Group at the top of the page.
-
On the Step 6 page, perform the following steps to allow incoming HTTP and HTTPS traffic (by default EC2 instances accept only SSH traffic):
-
Click the Add Rule button below the table, then select HTTP from the drop‑down menu in the Type column. For the purposes of this tutorial, we are allowing access from any IP address (the value in the Source column is Anywhere 0.0.0.0/0, ::/0). For production environments, we recommend you follow the warning on the page which mandates use of security groups to control access.
-
Repeat the previous step for HTTPS.
-
Click the Review and Launch button at the bottom of the page.
-
-
On the Step 7 page, click the Launch button at the bottom.
-
In the box that pops up, create a new key pair:
-
Select Create a new key pair from the upper drop‑down menu.
-
Select a key pair type. In this tutorial, we’re selecting RSA.
-
Type a name in the Key pair name field, such as NGINX_key.
-
Click the Download Key Pair button.
-
As shown in the animated screenshot below, a check box replaces the Download Key Pair button. Click it to indicate that you can access the private key.
-
Click the Launch Instances button.
-
-
In your file manager utility, move the downloaded .pem file (in the tutorial, NGINX_key.pem) to a secure location. For the tutorial we’re placing it in the /Desktop/NGINX directory.
-
If using a Windows terminal, follow the AWS instructions to download the PuTTYgen utility and convert the .pem file to a .ppk file.
-
On the Launch Status page, click the View Instances button at the bottom.
-
On the Instances page that opens, the new instance appears in the table. Give it a name:
-
Click the pencil icon in the Name column.
-
Type the name in the Edit Name pop‑up box and click the Save button.
-
-
Click the Connect button at the top of the screen. A window like the following pops up. Open the SSH client tab and follow the instructions to connect to the instance. If using Windows, substitute .ppk for .pem in the commands.
Installing NGINX Software
Now that your AWS environment is set up, it’s time to install either NGINX Open Source or NGINX Plus, which you can try free for 30 days. Both options work in the context of this tutorial, but if you want to further explore the advanced features in NGINX Plus, please request a free trial.
Installing NGINX Open Source
Most Linux distributions and BSD variants make NGINX Open Source available in their standard package repositories, but it’s usually not the latest version. We recommend downloading NGINX Open Source directly from nginx.org. There are just a few extra steps for adding the NGINX repository to the Ubuntu package manager (apt
).
To install NGINX Open Source, follow these steps:
-
Access your terminal.
-
Download the NGINX signing key:
$ sudo wget http://nginx.org/keys/nginx_signing.key
-
Add the key:
$ sudo apt-key add nginx_signing.key
-
Change directory to /etc/apt.
$ cd /etc/apt
-
Edit the sources.list file, appending this text at the end:
deb http://nginx.org/packages/ubuntu focal nginx deb-src http://nginx.org/packages/ubuntu focal nginx
Note: The
focal
keyword in each of these lines corresponds to Ubuntu 20.04. If you are using a different version of Ubuntu, substitute the first word of its release code name (for example,bionic
for Ubuntu 18.04). -
Update the NGINX software:
$ sudo apt-get update
-
Install NGINX:
$ sudo apt-get install nginx
-
Type
Y
when prompted. -
Start NGINX:
$ sudo systemctl start nginx.service
-
Check its status:
$ sudo systemctl status nginx.service
-
Continue to Opening Your Web Page.
Installing NGINX Plus
-
If you don’t already have NGINX Plus, sign up for a 30‑day free trial.
-
When you receive the email notification that your trial subscription is available, follow the instructions provided to download your security certificate, private key, and JWT, and then to install NGINX Plus.
-
When installation is complete and NGINX Plus is running, continue to Opening Your Web Page.
Opening Your Web Page
Now that you’ve started the NGINX software, take a look at the web page that NGINX and NGINX Plus serve by default before you configure them to deliver your site’s content. Follow these steps:
-
Navigate to the Instances tab on the EC2 Dashboard if you are not there already. (One way is to click Services in the top Console navigation bar, EC2 in the Compute section, and Instances in the left‑hand navigation column.)
-
Scroll right in the table until you can see the instance’s public IP address in the Public IPv4 address column (in the screenshot, it’s 3.22.51.xxx). Select the address and copy it into the paste buffer.
-
Open a new browser tab and paste the address into the address bar. The default Welcome to nginx! page appears, indicating that NGINX is installed and running but not yet configured.
Setting Up Sample Files
With a working version of NGINX or NGINX Plus installed, it’s time to put it to good use! Begin by setting up some files and directories.
-
Change directory to your home directory if you are not already there. In the following instructions, it is /home/ubuntu.
-
Create a directory called public_html and change into it.
-
In the public_html directory, create a file called index.html and a directory called application1.
-
In the application1 directory, create a file called app1.html with some text in it.
-
Change back to your home directory.
-
Create a directory called data.
-
In the data directory, create a directory called images.
Serving Pages and Images
Our first use case for NGINX or NGINX Plus is to serve pages and images to users via a web page.
-
Change directory to /etc/nginx/conf.d.
-
Rename default.conf to default.conf.bak to prevent NGINX or NGINX Plus from using it as the default configuration file.
-
Create a file called server1.conf with this configuration in it:
server { root /home/ubuntu/public_html; location /application1 { } location /images { root /home/ubuntu/data; } }
Directive documentation:
location
,root
,server
-
Change directory to ~/data/images.
-
Find an image that you want to serve and copy it to the directory (~/data/images). As an example, the following command copies over the NGINX logo:
$ curl -o NGINX-logo.png https://www.nginx.com/wp-content/uploads/2021/11/NGINX-logo-2020.png
-
Reload NGINX or NGINX Plus:
$ sudo nginx -s reload
-
In a web browser request the image at this URL, where NGINX-server is the public IP address of your EC2 instance:
https://NGINX-server/images/NGINX-logo.png
-
Also access the application and observe what you get:
https://NGINX-server/application1/app1.html
Setting Up a Proxy Server
Now that you have a working web server, it’s time to learn how to configure it to route traffic. This capability enables you to pass traffic through to other servers and is a major step towards setting up load balancing. Follow these steps:
-
In the ~/data directory, create a directory called server2.
-
In the server2 directory, create a directory called sampleApp.
-
In the sampleApp directory, create a file named index.html with some text in it.
-
Change directory to /etc/nginx/conf.d.
-
Create a file called server2.conf with this configuration in it:
server { listen 8080; root /home/ubuntu/data/server2; }
Directive documentation:
listen
,root
,server
-
Modify server1.conf by adding a
proxy_pass
directive in the firstlocation
block, as follows:server { root /home/ubuntu/public_html; location /application1 { proxy_pass http://localhost:8080/sampleApp; } location /images { root /home/ubuntu/data; } }
Directive documentation:
location
,proxy_pass
,root
,server
-
Reload NGINX or NGINX Plus:
$ sudo nginx -s reload
-
Access the following URL in your browser and observe what has changed compared to when you accessed it in Serving Pages and Images:
https://NGINX-server/application1/index.html
So that’s it! You now have a working Ubuntu instance running NGINX, which is ready to run as a proxy server.
For instructions on deploying NGINX and NGINX Plus on AWS for additional use cases, see our deployment guides.
Conclusion
In this tutorial, you learned how to set up NGINX or NGINX Plus to serve files and images over the Internet, and to act as a reverse proxy. If you want to learn about NGINX in more depth, we offer the NGINX Core training course (instructor‑led or on‑demand) which covers the topics from this tutorial as well as more essentials of web serving and application delivery, including load balancing, location‑based routing, and security. Also check out the documentation at nginx.org and the NGINX Plus Admin Guide – except as noted, the articles apply to NGINX Open Source as well as NGINX Plus.
Free O’Reilly eBook: The Complete NGINX Cookbook
Updated for 2022 – Your Guide to Everything NGINX
В этой статье будем учиться, как правильно устанавливать и настраивать основные части конфигурации NGINX на примере ОС Linux Debian.
Представьте ситуацию: вы создали веб-приложение и теперь ищете подходящий веб-сервер для его размещения. Ваше приложение может состоять из нескольких статических файлов – HTML, CSS и JavaScript, бэкэнда API-сервиса или даже нескольких веб-сервисов. Использование NGINX может быть тем, что вы ищете, и для этого есть несколько причин.
NGINX – это мощный веб-сервер, использующий не потоковую, управляемую событиями архитектуру, которая позволяет ему превосходить Apache при правильной настройке (подробная информация здесь). Он также может выполнять другие важные функции, такие как балансировка нагрузки, кеширование HTTP и использование в качестве обратного прокси.
Базовая установка – архитектура
Существует два способа установки NGINX – либо использовать установку из пакетов, либо компилировать из исходников.
Первый способ быстрее и проще, но компиляция из исходников дает возможность подключать сторонние библиотеки и модули, что делает NGINX еще более мощным инструментом. Такой способ позволит настроить все “под себя” и для нужд приложения.
Чтобы установить веб-сервер из пакета в ОС Debian, нужно всего лишь:
sudo apt-get update sudo apt-get install nginx
По завершении процесса установки вы можете проверить, что все в порядке, выполнив приведенную ниже команду, которая выведет на экран установленную версию NGINX.
sudo nginx -v nginx version: nginx/1.6.2
Ваш веб-сервер будет установлен в директорию /etc/nginx/. Если перейти в эту директорию, можно увидеть несколько файлов и папок. Наиболее важные из них – это файл nginx.conf и папка sites-available.
Конфигурирование – основы
Основной файл настроек NGINX – это файл nginx.conf, который по умолчанию выглядит так:
user www-data; worker_processes 4; pid /run/nginx.pid; events { worker_connections 768; # multi_accept on; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; gzip_disable "msie6"; # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; # gzip_http_version 1.1; # gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
Файл состоит из директив. Первая из них – events, а вторая – http. Структура из этих блоков создает основу всей конфигурации. Параметры и свойства родителей наследуется всеми дочерними блоками, и могут быть переопределены при необходимости.
Конфигурирование – параметры
Различные параметры этого файла могут быть изменены при необходимости, но NGINX настолько прост, что все будет работать с настройками по умолчанию. Рассмотрим некоторые важные параметры конфигурационного файла:
- worker_processes: эта настройка описывает число рабочих процессов, которые сервер будет использовать. Поскольку NGINX является однопоточным, это число обычно эквивалентно количеству ядер процессора.
- worker_connections: максимальное число одновременных подключений для каждого worker_processes, оно сообщает, сколько людей одновременно NGINX сможет обслужить. Чем это число больше, тем больше запросов пользователей сможет обработать веб-сервер.
- access_log & error_log: это файлы, которые сервер использует для логирования всех ошибок и попыток входа. Эти логи нужно в первую очередь проверять при возникновении проблем и при поиске неисправностей.
- gzip: это свойство устанавливает настройки сжатия GZIP для NGINX ответов. Если включить его в сочетании с другими параметрами, производительность ресурса может значительно вырасти. Из дополнительных параметров GZIP следует отметить gzip_comp_level, который означает уровень компрессии и бывает от 1 до 10. Обычно, это значение не должно превышать 6 т. к. при большем числе прирост производительности незначительный. gzip_types – это список типов ответов, к которым будет применяться сжатие.
Ваш установленный сервер может поддерживать больше одного сайта, а файлы, которые описывают сайты вашего сервера, находятся в каталоге /etc/nginx /sites-available.
Файлы в этом каталоге не являются «живыми» – у вас может быть столько файлов, описывающих сайты, сколько вы хотите, но веб-сервер ничего не будет с ними делать, если они не будут привязаны символической ссылкой на папку /etc/nginx/site-enabled.
Это дает вам возможность быстро помещать сайты в онлайн и отправлять их в автономный режим без фактического удаления каких-либо файлов. Когда вы будете готовы перевести сайт в онлайн – делайте символическую ссылку на sites-enabled и перезапускайте процесс.
Рабочая директория
В директории sites-available находится конфигурационный файл для виртуальных хостов. Этот файл позволяет настроить веб-сервер на мультисайтовость, чтобы каждый сайт имел свой отдельный конфиг. Сайты в этом каталоге не активны и будут включены только в том случае, если мы создадим символическую ссылку на папку sites-enabled.
Теперь создайте новый файл для своего веб-приложения или отредактируйте дефолтный. Типичный конфиг выглядит так:
upstream remoteApplicationServer { server 10.10.10.10; } upstream remoteAPIServer { server 20.20.20.20; server 20.20.20.21; server 20.20.20.22; server 20.20.20.23; } server { listen 80; server_name www.customapp.com customapp.com root /var/www/html; index index.html location / { alias /var/www/html/customapp/; try_files $uri $uri/ =404; } location /remoteapp { proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://remoteAPIServer/; } location /api/v1/ { proxy_pass https://remoteAPIServer/api/v1/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_redirect http:// https://; } }
Этот файл имеет похожую структуру на nginx.conf – все та же блочная иерархия (и все они также вложены внутри HTTP-контекста nginx.conf, поэтому они также наследуют все от него).
Блок server описывает специфику работы виртуального сервера, который будет обрабатывать запросы пользователей. У вас может быть несколько таких блоков, и веб-сервер сам будет выбирать между ними на основании директив listen и server_name.
Внутри блока сервера мы определяем несколько контекстов location, которые используются для определения того, как обрабатывать клиентские запросы. Всякий раз, когда приходит запрос, сервер будет пытаться сопоставить свой URI с одним из этих определений location и обрабатывать его соответствующим образом.
Существует много важных директив, которые могут быть использованы, среди них:
- try_files: указывает на статический файл, находящийся в root-директории.
- proxy_pass: запрос будет отправлен на указанный прокси-сервер.
- rewrite: переписывает входящий URI основываясь на регулярном выражении, чтобы другой блок обработал его.
Блок upstream определяет пул серверов, на который будут отправляться запросы. После того, как мы создадим блок upstream и определим сервер внутри него, мы можем ссылаться на него по имени внутри наших блоков location. Кроме того, в upstream контексте может быть назначено множество серверов, поэтому NGINX будет выполнять некоторую балансировку нагрузки при проксировании запросов.
После того, как все настройки завершены и сайт перемещен в нужную директорию, мы можем запускать наш веб-сервер следующей командой:
sudo service nginx start
После какого-либо изменения в файле конфигурации, мы должны заставить процесс NGINX перечитать конфиг (без перезагрузки) такой командой:
service nginx reload
И наконец, мы можем проверить состояние процесса командой:
service nginx status
Заключение
Даже имея огромное количество настраиваемых параметров, NGINX может стать отличным вариантом для управления приложением, или быть использованным в качестве HTTP прокси, или балансировщика нагрузки для веб-сервера. Понимание как работает веб-сервер, и как он обрабатывает запросы, позволит гибко настроить и сбалансировать нагрузку ваших приложений.
Другие материалы по теме:
- Лучший видеокурс, который сделает вас Linux админом
- Защита системы Linux: 11 советов по безопасности
- 7 книг по UNIX/Linux