Конфигурация nginx
nginx является одним из самых используемых веб-серверов в мире. В самом начале своего пути я не знал про этот прекрасный веб-сервер и мне приходилось пользоваться Apache HTTP Server, который хоть и настраивался более гибко, но, было невыносимо разобраться во всех настройках для того чтобы просто запустить его.
Что такое nginx?
nginx – это веб-сервер, который может быть использован как реверс-прокси, балансировщик нагрузки и прокси для SMTP. Данный веб-сервер необычайно простой в конфигурации.
Установка nginx
Для того чтобы установить nginx достаточно выполнить всего одну команду в терминале:
sudo apt install nginx # Debian-based дистрибутивы
sudo dnf install nginx # RHL-based дистрибутивы
sudo pacman -Syu nginx # Arch-based дистрибутивы
brew install nginx     # MacOS
После этого действия у нас установится nginx. Все конфигурации этого сервера будут лежать в /etc/nginx.
Информация
Для MacOS конфигурации будут лежать в /opt/homebrew/etc/nginx
Устройство nginx
Мастер-процесс — процесс, читающий и выполняющий конфигурацию сервера. Исходя из конфигурации данный процесс управляет воркерами. Данный процесс не обрабатывает никаких запросов, он нужен чтобы управлять другими процессами.
Воркер-процесс — процесс, который обрабатывает запросы направленные серверу. Именно эти процессы и будут обрабатывать HTTP-запросы (или запросы с другими протоколами). nginx будет стараться перераспределять запросы между множеством воркеров для того чтобы распределить нагрузку. Количество воркер-процессов задается в конфигурации или вычисляется автоматически исходя из ресурсов сервера (количества ядер в CPU).
При запуске nginx, он запускает один мастер-процесс, который обрабатывает конфигурацию и запускает необходимое количество воркеров.
В случае если если мы поменяем нашу конфигурацию и скажем мастер-процессу работать по новой конфигурации, то мастер-процесс отправит воркерам сообщение о том, что им нужно завершиться. Те воркеры, которые не обрабатывают никаких запросов – завершатся сразу. Если воркер в момент получения сообщения обрабатывал какой-либо запрос, то он завершится сразу же после того как доделает всю работу над запросом.
Сигналы
Мы можем запустить nginx с помощью одноименной команды — nginx.
Когда nginx запущен, то мы можем управлять им с помощью сигналов. Сигналы же есть следующие:
  • stop
  • quit
  • reload
  • reopen
Сигнал stop понадобится нам в случае если мы захотим остановить все воркеры, quit понадобится в случае если захотим выключить nginx, reload пригодится при изменении конфигурации.
System Control
Мы также можем управлять nginx с помощью утилиты systemctl, которая используется для управления демонами в большинстве UNIX-подобных систем.
Информация
Для справки: Демон — программа, которая работает в фоновом режиме.
Мы можем управлять сервисом nginx с помощью следующих команд:
sudo systemctl enable        nginx # Nginx будет запускаться при включении системы
sudo systemctl disable       nginx # Nginx будет не будет запускаться при включении системы
sudo systemctl start         nginx # Запустить nginx прямо сейчас
sudo systemctl stop          nginx # Остановить nginx прямо сейчас
sudo systemctl enable  --now nginx # Совмещение первой и третьей команды
sudo systemctl disable --now nginx # Совмещение второй и четвертой команды
sudo systemctl status        nginx # Просмотреть статус сервиса nginx
Конфигурационный файл
Вся конфигурация в nginx делится на:
  • Модули: Самостоятельные блоки конфигурации, которые можно подключать и отключать;
  • Директивы: инструкции для конфигурации;
    • Строчные директивы: Простая инструкция вида ключ значение1 значение2 значение 3;;
    • Блочные директивы: Инструкция, которая содержит строчные директивы, вместо значений у нее идут фигурные скобки { ... };
    • Контексты: Блочные директивы, которые содержат другие блочные директивы;
Информация
Директивы, которые хранятся вне любого контекста на самом деле находятся в директиве main;
Одними из главных блочных директив являются:
  • http: (Располагается внутри main) Предоставляет контекст конфигурационного файла, в котором указываются директивы HTTP-сервера.
    • server: (Располагается внутри http) Задаёт конфигурацию для виртуального сервера. Чёткого разделения виртуальных серверов на IP-based (на основании IP-адреса) и name-based (на основании поля “Host” заголовка запроса) нет.
      • location: (Располагается внутри server) Устанавливает конфигурацию в зависимости от URI запроса.
  • events: (Располагается внутри main) Предоставляет контекст конфигурационного файла, в котором указываются директивы, влияющие на обработку соединений.
Сам же конфигурационный файл nginx находится в /etc/nginx/nginx.conf, однако, конфигурация определенных виртуальных сайтов будет находится в /etc/nginx/sites-available/, там уже лежит файл default, который мы можем менять не беспокоясь о том, что мы все сломаем.
На всякий случай можете сделать бэкап данного файла с помощью следующей команды:
mv /etc/nginx/sites-available/default{,.backup}
Если мы выведем все файлы в /etc/nginx, то там будет примерно следующее:
tree /etc/nginx -L 1
/etc/nginx
|-- conf.d               # Директория для пользовательских конфигураций
|-- fastcgi.conf         # Конфигурация для обработки запросов с помощью FastCGI
|-- fastcgi_params       # Параметры для FastCGI
|-- koi-utf              # Хэшмапа с кодами для символов
|-- koi-win              # Хэшмапа с кодами для символов
|-- mime.types           # MIME-типы
|-- modules-available    # Директория с доступными модулями для подключения к конфигурации
|-- modules-enabled      # Директория с включенными модулями
|-- nginx.conf           # Главный конфигурационный файл nginx
|-- proxy_params         # Параметры для Reverse Proxy
|-- scgi_params          # Параметры для SCGI
|-- sites-available      # Доступные конфигурации сайтов для подключения к конфигурации
|-- sites-enabled        # Включенные конфигурации сайтов
|-- snippets             # Сниппеты
|-- uwsgi_params         # Параметры для UWSGI
`-- win-utf              # Хэшмапа с кодами для символами
Раздача статики
Наш конфигурационный файл может выглядеть следующим образом:
http {
    # Добавляем новый виртуальный сервер
    server {
        # При запросе на / будут отдаваться файлы (index.html, index.htm, и так далее)
        # из директории /data/www
        location / {
            root /data/www;
        }

        # При запросе на /images/* будут отдаваться файлы
        # из директории /data/images/*
        location /images/ {
            root /data;
        }
    }
}
В данном случае root — это директива, которая указывает на путь, где nginx должен искать файлы, которые можно будет отдать клиенту.
В первом блоке location / мы говорим о том, что файлы которые может запросить клиент нужно искать по адресу /data/www.
Во втором же блоке мы говорим о том, что nginx должен искать файлы картинок в директории /data, если пользователь будет запрашивать файлы по URI, который начинается с /images . Важно отметить, что путь /data и URI /images конкатенируются, то есть по итогу nginx будет искать картинки в директории /data/images/.
По умолчанию конфигурации такого рода, как эта, могут находиться в /etc/nginx/sites-available. Для того чтобы включить конфигурацию достаточно просимлинкать ее в /etc/nginx/sites-enabled:
ln -s /etc/nginx/sites-available/<файл конфигурации> /etc/nginx/sites-enabled
Информация
Для справки: по умолчанию сервер nginx будет слушать порт :80. Он является стандартным портом для HTTP, его не нужно дописывать в конец адреса. То есть, http://google.com – это то же самое, что и http://google.com:80.
Реверс-прокси
Реверс-прокси в nginx настроить тоже достаточно просто. Сначала мы посмотрим на готовый конфиг, а потом разберем его на части:
server {
    location / {
        proxy_pass http://localhost:8080/;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}
В данном случае все запросы, которые идут на / проксируются на сервер http://localhost:8080/. Важно обратить внимание на директиву proxy_pass, именно она и говорит что запросы будут проксироваться.
Также, в данном примере мы можем увидеть, что все запросы, которые в конце содержат .gif, .jpg и .png будут обрабатываться немного иначе – ресурсы будут браться из директории /data/images. Мы можем использовать regex (как в данном случае) прямо с директивой location в случае если у location в начале стоит символ тильды (он же ~).
Пример стандартной конфигурации
server {
    listen 80;
    server_name static-site.ericjflynn.com;
    root /var/www/static-site;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}
В данном случае мы объявили новый конфигурационный блок для сервера, который будет: прослушиваться на порту 80.
  • Директива server_name указывает на то, по какому домену клиент сможет обращаться к серверу.
  • Директива root указывает на то, в какой директории находятся все статические файлы, которые возможно запросит клиент.
  • Директива index указывает на то какой по умолчанию файл является "входной точкой", то есть при обращении на / сервер будет отдавать именно index.html.
  • Директива try_files будет смотреть на путь, по которому обратился клиент и попытается найти файлы или директории, которые указаны в URI. Если таковых не найдется, то сервер вернет 404
Логи
Важной частью работы nginx являются логи. Мы можем просмотреть логи в директориях: /usr/local/nginx/logs или /var/log/nginx.
Там будут храниться два файла access.log и error.log, данные файлы можно просмотреть с помощью команды tail -f (tail following – просмотр хвоста файла с отслеживанием):
tail -f /var/log/nginx/error.log # Отслеживание ошибок
Также мы можем посмотреть на статус обрабатываемых запросов с помощью systemctl:
systemctl status nginx.service