Зачем собирать Nginx из исходников: когда пакетов недостаточно
Стандартная установка Nginx через apt или yum удобна для быстрого старта. Вы получаете стабильную версию с базовым набором модулей за пару минут. Проблема возникает, когда задача выходит за рамки типового HTTP-сервера: нужно проксировать TCP-трафик к базе данных, организовать видеовещание через RTMP или добавить скриптинг на Lua. Предсобранные пакеты содержат фиксированный набор модулей, определённый мейнтейнерами дистрибутива. Добавить сторонний модуль или включить специфичный функционал в готовый бинарник невозможно.
Сборка из исходного кода даёт полный контроль над составом Nginx. Вы сами решаете, какие модули будут вкомпилированы статически, какие загружаться динамически, а какие исключены для уменьшения размера бинарника. Второй важный фактор - безопасность. При самостоятельной сборке вы можете применить свежие патчи безопасности сразу после их выхода, не дожидаясь обновления пакетов в репозитории вашего дистрибутива. Для продакшен-сред, где критичен каждый час, это весомое преимущество.
Типичные задачи, требующие кастомной сборки: балансировка TCP/UDP-трафика через модуль stream, организация прямых трансляций видео с помощью RTMP, тонкое управление HTTP-заголовками через headers-more, геотаргетинг на основе GeoIP2, создание сложной логики обработки запросов на языке Lua. Если ваш проект использует хотя бы один из этих сценариев, стандартных пакетов недостаточно. Процесс сборки, описанный в этом руководстве, проверен на актуальных версиях Nginx и библиотек по состоянию на июль 2026 года. После его выполнения вы получите бинарник, собранный точно под ваши задачи, и готовый к использованию в production.
Выбор модулей: статические vs динамические и что вам нужно
Перед запуском configure важно определить, какие модули включать и в каком виде. Nginx поддерживает два способа интеграции модулей: статическую компиляцию в ядро и динамическую загрузку через директиву load_module. Статические модули компилируются непосредственно в бинарный файл nginx, всегда активны и не требуют дополнительных действий при запуске. Это даёт минимальную задержку при обработке запросов, но увеличивает размер бинарника и потребление памяти. Динамические модули хранятся в отдельных .so-файлах и загружаются только при явном указании в конфигурации. Такой подход экономит ресурсы, когда модуль нужен эпизодически, и упрощает обновление отдельного модуля без пересборки всего Nginx.
Для критичных к производительности компонентов, таких как HTTP/SSL или stream, рекомендуется статическая компиляция. Эти модули обрабатывают каждый запрос, и накладные расходы на динамическую загрузку здесь неоправданны. Для редко используемых или экспериментальных модулей выбирайте динамический вариант. Это позволит отключать их без перекомпиляции и сократит время сборки при обновлении Nginx.
Список востребованных модулей, ради которых часто затевается сборка:
- stream - проксирование и балансировка TCP/UDP-трафика: базы данных, почтовые серверы, DNS.
- RTMP - приём и передача видеопотоков, организация прямых трансляций и перекодирования.
- headers-more - добавление, удаление и модификация HTTP-заголовков на лету.
- Lua (ngx_http_lua_module) - выполнение скриптов Lua непосредственно в контексте Nginx для сложной маршрутизации и обработки запросов.
- GeoIP2 - определение географического положения клиента по IP с использованием баз MaxMind.
- fancyindex - красивое оформление листинга директорий с возможностью кастомизации.
Модуль stream: проксирование TCP и UDP
Модуль stream решает задачу проксирования трафика на транспортном уровне. В отличие от HTTP-блока, который работает с заголовками и методами HTTP, stream оперирует TCP- и UDP-соединениями напрямую. Это нужно для балансировки подключений к базам данных PostgreSQL или MySQL, проксирования SMTP/IMAP-трафика почтовых серверов, организации доступа к внутренним DNS-резолверам. В стандартных пакетах Debian и Ubuntu модуль stream отсутствует - он не входит в сборку по умолчанию. На CentOS/RHEL через EPEL модуль доступен, но только в статическом варианте. Пример минимальной конфигурации stream для проксирования TCP-трафика к внутреннему серверу PostgreSQL:
stream {
upstream postgres_backend {
server 10.0.1.10:5432;
server 10.0.1.11:5432 backup;
}
server {
listen 5432;
proxy_pass postgres_backend;
proxy_connect_timeout 5s;
}
}
Эта конфигурация принимает подключения на порт 5432 и перенаправляет их на один из серверов PostgreSQL. Директива backup указывает, что второй сервер используется только при недоступности первого. Таймаут подключения в 5 секунд предотвращает зависание клиентов при проблемах с бэкендом.
Модуль RTMP: организация видеовещания
RTMP-модуль - сторонняя разработка, которую нет в официальном репозитории Nginx. Он добавляет поддержку протокола Real-Time Messaging Protocol, используемого для передачи аудио и видео через интернет. С его помощью Nginx может принимать видеопотоки от кодировщиков вроде OBS Studio или ffmpeg и раздавать их зрителям. Типичный сценарий: организация прямой трансляции с камеры на сайт без использования сторонних сервисов. Модуль также умеет перекодировать потоки в HLS и DASH - форматы, поддерживаемые современными браузерами. Для включения RTMP используется флаг --add-module с указанием пути к исходникам модуля. Это статическая компиляция, динамический вариант для RTMP не поддерживается.
Подготовка окружения для сборки
Сборка Nginx требует набора библиотек для компиляции и работы модулей. Отсутствие хотя бы одной зависимости приведёт к ошибке на этапе configure. Дальше приведены команды для двух основных семейств дистрибутивов. Выполните их перед началом работы.
Установка зависимостей на Debian/Ubuntu
sudo apt update && sudo apt install build-essential libpcre3-dev libssl-dev zlib1g-dev libxml2-dev libxslt1-dev libgd-dev libgeoip-dev
Назначение каждого пакета: build-essential включает компилятор gcc, утилиту make и базовые заголовочные файлы. libpcre3-dev предоставляет библиотеку PCRE для обработки регулярных выражений в директивах location и rewrite. libssl-dev нужна для модуля HTTP/SSL и поддержки HTTPS. zlib1g-dev обеспечивает сжатие ответов через gzip. libxml2-dev и libxslt1-dev требуются для модулей трансформации XML/XSLT. libgd-dev используется модулем image_filter для обработки изображений. libgeoip-dev - для работы GeoIP-модуля с базами MaxMind.
Установка зависимостей на CentOS/RHEL
sudo yum groupinstall 'Development Tools' && sudo yum install pcre-devel openssl-devel zlib-devel libxml2-devel libxslt-devel gd-devel geoip-devel
Для CentOS 8 и новее, а также RHEL 8/9 замените yum на dnf. Команда groupinstall 'Development Tools' устанавливает тот же набор инструментов сборки, что и build-essential в Debian. Имена пакетов отличаются суффиксом -devel вместо -dev, но назначение идентично.
Если планируете использовать модуль GeoIP2 с базами MaxMind, дополнительно установите libmaxminddb-dev (Debian/Ubuntu) или libmaxminddb-devel (CentOS/RHEL). Для модуля Lua потребуется luajit и luajit-devel. Эти зависимости не входят в базовый список и устанавливаются отдельно под конкретную задачу.
Загрузка и проверка исходного кода Nginx
Исходный код загружается с официального сайта nginx.org. Используйте стабильную версию для production-сред. На момент написания статьи актуальна стабильная ветка 1.26.x. Загрузка и проверка целостности выполняются в четыре шага.
Шаг 1: перейдите на страницу загрузки Nginx и скопируйте ссылку на архив стабильной версии. Загрузите его через wget:
wget https://nginx.org/download/nginx-1.26.2.tar.gz
Шаг 2: загрузите файл с контрольной суммой и импортируйте GPG-ключ для проверки подписи:
wget https://nginx.org/download/nginx-1.26.2.tar.gz.asc
wget https://nginx.org/keys/nginx_signing.key
gpg --import nginx_signing.key
Шаг 3: проверьте подпись архива. Команда gpg --verify сравнивает подпись из .asc-файла с фактическим содержимым архива:
gpg --verify nginx-1.26.2.tar.gz.asc nginx-1.26.2.tar.gz
Ожидаемый вывод: Good signature from "nginx signing key
Шаг 4: распакуйте архив и перейдите в директорию с исходниками:
tar -xzf nginx-1.26.2.tar.gz
cd nginx-1.26.2
Проверка контрольной суммы и GPG-подписи гарантирует, что архив не повреждён при загрузке и не подменён злоумышленником. Пропускать этот шаг не рекомендуется, особенно при сборке для production-окружения.
Конфигурирование сборки: флаги ./configure для ваших задач
Скрипт configure анализирует систему на наличие зависимостей и генерирует Makefile с параметрами компиляции. Базовый синтаксис:
./configure [флаги модулей] [флаги путей]
Флаги путей определяют, куда будут установлены бинарник, конфигурационные файлы и логи. Основные параметры:
- --prefix - корневая директория установки (по умолчанию /usr/local/nginx).
- --sbin-path - путь к исполняемому файлу nginx.
- --conf-path - путь к основному конфигурационному файлу.
- --error-log-path и --http-log-path - пути к логам ошибок и доступа.
- --pid-path - путь к файлу с PID основного процесса.
Флаги модулей делятся на три категории. Первая - включение стандартных модулей, которые не собираются по умолчанию: --with-http_ssl_module, --with-stream, --with-http_v2_module. Вторая - отключение ненужных модулей для уменьшения размера: --without-http_autoindex_module, --without-http_fastcgi_module. Третья - добавление сторонних модулей: --add-module=/path/to/module для статической компиляции и --add-dynamic-module=/path/to/module для динамической.
Для динамической загрузки стандартных модулей используйте суффикс =dynamic: --with-stream=dynamic, --with-http_geoip_module=dynamic. Не все стандартные модули поддерживают динамическую загрузку - проверяйте документацию к конкретному модулю.
Пример конфигурации для RTMP-сервера
Перед запуском configure клонируйте репозиторий RTMP-модуля в домашнюю директорию:
git clone https://github.com/arut/nginx-rtmp-module.git ~/nginx-rtmp-module
Команда configure для сборки Nginx с поддержкой RTMP и SSL:
./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--with-http_ssl_module \
--with-http_v2_module \
--add-module=$HOME/nginx-rtmp-module
Эта конфигурация устанавливает Nginx в стандартные системные пути, что упрощает интеграцию с systemd и привычную работу с конфигурацией. Модуль RTMP компилируется статически и будет доступен сразу после запуска.
Пример конфигурации с динамическими модулями stream и GeoIP2
Для динамической сборки stream и добавления стороннего GeoIP2-модуля:
./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--with-http_ssl_module \
--with-stream=dynamic \
--add-dynamic-module=$HOME/ngx_http_geoip2_module
После установки динамические модули будут размещены в директории /etc/nginx/modules. Для их активации добавьте в начало nginx.conf:
load_module modules/ngx_stream_module.so;
load_module modules/ngx_http_geoip2_module.so;
Такой подход позволяет отключать модули простым комментированием директив load_module без пересборки.
Компиляция и установка
После успешного выполнения configure запустите компиляцию:
make -j$(nproc)
Флаг -j$(nproc) задействует все доступные ядра процессора для параллельной сборки. На современных серверах это сокращает время компиляции с нескольких минут до 30-40 секунд. Если компиляция прерывается с ошибкой, выполните make clean перед повторной попыткой - это удалит промежуточные файлы и предотвратит конфликты.
Для тестирования собранного бинарника без замены рабочей версии используйте установку в отдельный префикс:
make install DESTDIR=/opt/nginx-test
Это установит Nginx в /opt/nginx-test/etc/nginx со всеми файлами. Запустите тестовый экземпляр на нестандартном порту, проверьте работу модулей и только после этого выполняйте установку в систему:
sudo make install
Если в системе уже установлен Nginx из пакетов, предварительно удалите его: sudo apt remove nginx (Debian/Ubuntu) или sudo yum remove nginx (CentOS/RHEL). Конфигурационные файлы из /etc/nginx при этом сохранятся - пакетный менеджер не удаляет директории с пользовательскими данными. После установки ваша конфигурация останется на месте и будет подхвачена новым бинарником.
Создание systemd unit-файла
Для управления Nginx через systemctl создайте файл /etc/systemd/system/nginx.service:
[Unit]
Description=Nginx HTTP and reverse proxy server
After=network.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
После создания файла выполните:
sudo systemctl daemon-reload
sudo systemctl enable nginx
sudo systemctl start nginx
Директива ExecStartPre выполняет проверку синтаксиса конфигурации перед каждым запуском. Если nginx -t обнаружит ошибку, сервис не запустится, что предотвращает падение production-сервера из-за опечатки в конфиге.
Типичные ошибки при сборке и их решение
Ошибки при сборке Nginx делятся на две категории: проблемы этапа configure и проблемы этапа make. Дальше разобраны наиболее частые ситуации с симптомами, причинами и решениями.
Ошибки этапа configure
Симптом: ./configure: error: the HTTP rewrite module requires the PCRE library.
Причина: Отсутствует библиотека PCRE или её заголовочные файлы.
Решение: Установите libpcre3-dev (Debian/Ubuntu) или pcre-devel (CentOS/RHEL).
Симптом: ./configure: error: SSL modules require the OpenSSL library.
Причина: Отсутствует OpenSSL или его версия слишком старая. Nginx требует OpenSSL 1.0.2 и выше.
Решение: Установите libssl-dev или openssl-devel. Если в репозиториях старая версия, скачайте и соберите OpenSSL вручную, указав путь к нему через --with-openssl=/path/to/openssl.
Симптом: ./configure: error: the HTTP XSLT module requires the libxml2/libxslt libraries.
Причина: Отсутствуют библиотеки для обработки XML/XSLT.
Решение: Установите libxml2-dev и libxslt1-dev. Если XSLT-модуль не нужен, отключите его флагом --without-http_xslt_module.
Ошибки этапа make
Симптом: undefined reference to `SSL_CTX_set_alpn_select_cb'
Причина: Версия OpenSSL в системе не поддерживает ALPN (Application-Layer Protocol Negotiation), необходимый для HTTP/2.
Решение: Обновите OpenSSL до версии 1.0.2 или новее. На старых дистрибутивах может потребоваться сборка OpenSSL из исходников с последующим указанием пути через --with-openssl.
Симптом: fatal error: luajit.h: No such file or directory
Причина: Указан модуль Lua, но заголовочные файлы LuaJIT не найдены.
Решение: Установите luajit и libluajit-5.1-dev. Если библиотека установлена в нестандартном пути, укажите его через переменные окружения: export LUAJIT_LIB=/path/to/lib LUAJIT_INC=/path/to/include.
Симптом: make: *** No targets specified and no makefile found. Stop.
Причина: Этап configure не выполнился успешно или не запускался вовсе.
Решение: Запустите ./configure с нужными флагами и убедитесь, что он завершился без ошибок. Появится файл Makefile в текущей директории.
Проверка работоспособности: убеждаемся, что всё работает
После установки проверьте, что Nginx запускается и содержит нужные модули. Первая команда для диагностики - nginx -V. Она выводит полный список аргументов configure, с которыми был собран бинарник, включая все вкомпилированные модули:
nginx -V 2>&1 | grep -o 'with-[a-z_]*' | sort
Эта команда отфильтрует и отсортирует все включённые модули. Проверьте, что в выводе присутствуют модули, которые вы добавляли: with-stream, with-http_ssl_module, add-module для RTMP.
Проверка синтаксиса конфигурации перед запуском обязательна:
nginx -t
Ожидаемый вывод: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok и nginx: configuration file /etc/nginx/nginx.conf test is successful. Если есть ошибки, nginx -t укажет файл и строку с проблемой.
Для практической проверки HTTP-модулей используйте curl:
curl -I http://localhost
Ответ с HTTP-заголовками подтверждает, что HTTP-ядро работает. Для проверки модуля stream откройте TCP-соединение через telnet или nc:
nc -zv localhost 5432
Сообщение Connection to localhost 5432 port [tcp/postgresql] succeeded! означает, что stream-прокси принимает подключения. Для проверки RTMP-модуля используйте ffmpeg для отправки тестового потока:
ffmpeg -re -i /path/to/test.mp4 -c copy -f flv rtmp://localhost/live/stream
Отсутствие ошибок в выводе ffmpeg и появление записи в логах Nginx подтверждают работоспособность RTMP.
Автоматизация сборки: скрипт для повторяемости
Ручная сборка приемлема для одного сервера. Когда нужно развернуть Nginx с одинаковым набором модулей на десятке машин или регулярно обновлять сборку, процесс автоматизируют. Bash-скрипт, принимающий версию Nginx и список модулей, решает эту задачу. Пример минимального скрипта:
#!/bin/bash
NGINX_VERSION="${1:-1.26.2}"
PREFIX="/etc/nginx"
apt update && apt install -y build-essential libpcre3-dev libssl-dev zlib1g-dev
wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
tar -xzf nginx-${NGINX_VERSION}.tar.gz
cd nginx-${NGINX_VERSION}
./configure \
--prefix=${PREFIX} \
--sbin-path=/usr/sbin/nginx \
--conf-path=${PREFIX}/nginx.conf \
--with-http_ssl_module \
--with-stream \
--with-http_v2_module
make -j$(nproc) && make install
Для контейнеризованных сред удобнее Dockerfile. Он фиксирует все зависимости и шаги сборки в одном файле, гарантируя идентичность бинарника на любом хосте с Docker. Пример Dockerfile для сборки Nginx с RTMP:
FROM debian:bookworm-slim AS builder
RUN apt update && apt install -y build-essential libpcre3-dev libssl-dev zlib1g-dev git wget
RUN wget https://nginx.org/download/nginx-1.26.2.tar.gz && tar -xzf nginx-1.26.2.tar.gz
RUN git clone https://github.com/arut/nginx-rtmp-module.git /opt/nginx-rtmp-module
WORKDIR /nginx-1.26.2
RUN ./configure --add-module=/opt/nginx-rtmp-module --with-http_ssl_module && make -j$(nproc) && make install
FROM debian:bookworm-slim
COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx
COPY --from=builder /etc/nginx /etc/nginx
RUN apt update && apt install -y libpcre3 libssl3 zlib1g && rm -rf /var/lib/apt/lists/*
CMD ["nginx", "-g", "daemon off;"]
Многоэтапная сборка в Dockerfile уменьшает размер финального образа: в первом этапе устанавливаются все пакеты для компиляции, во втором копируется только готовый бинарник и runtime-зависимости. Такой образ занимает 30-40 МБ вместо 300+ МБ при одноэтапной сборке.
Автоматизация через скрипт или Dockerfile даёт два преимущества. Первое - воспроизводимость: вы всегда получаете идентичный бинарник, независимо от того, на какой машине запущена сборка. Второе - простота обновления: для перехода на новую версию Nginx достаточно изменить номер версии в скрипте и перезапустить его. Это критично для production-сред, где ручная сборка на каждом сервере создаёт риск расхождения конфигураций.
После сборки и установки стоит обратить внимание на мониторинг работы Nginx - это поможет отслеживать стабильность собранного бинарника под нагрузкой. Если ваша сборка включает модуль stream для балансировки TCP-трафика, ознакомьтесь с продвинутой настройкой балансировки нагрузки. Для проектов с передачей больших объёмов данных пригодятся настройки обработки больших файлов.