Подключение дополнительных модулей к NGINX не самая тривиальная вещь для веб-разработчиков. Рассмотрим эту задачу на примере сборки NGINX с модулем HTTP Redis (ngx_http_redis).
Раньше, для подключения модулей к NGINX, нужно было полностью компилировать и веб-сервер и желаемые модули, но начиная с версии 1.9.11 можно этого не делать, а обойтись командой make modules, но для этого необходимо правильно сконфигурировать всю сборку NGINX.
Итак, сначала нужно узнать какая версия NGINX установлена. Если меньше 1.9.11, то читаем Установка последней версии NGINX.
nginx -v
##
nginx version: nginx/1.13.5
Скачиваем и распаковываем в домашнюю директорию ту же самую версию NGINX (в нашем случае 1.13.5):
wget https://nginx.ru/download/nginx-1.13.5.tar.gz
tar -xzvf nginx-1.13.5.tar.gz
Скачиваем и распаковываем модуль HTTP Redis:
wget https://people.freebsd.org/~osa/ngx_http_redis-0.3.8.tar.gz
tar -xzvf ngx_http_redis-0.3.8.tar.gz
Итого, у нас должны быть:
1. Установленный и работающий NGINX >= 1.9.11
2. Скаченный дистрибутив NGINX той же версии, что в пункте 1
3. Скаченный дистрибутив модуля HTTP Redis
Теперь мы можем скомпилировать модуль и подключить его в файле nginx.conf командой load_module my_module.so.
Нужно узнать текущую конфигурацию билда NGINX, смотрим его командой:
nginx -V
Заходим в директорию, куда распаковался скаченный NGINX:
cd nginx-1.13.5/
Готовимся к билду. Он проходит в два этапа: «configure» и «make».
Configure
Нужно после команды ./configure поставить то, что показано у вас в команде nginx -V. В моём случае (Ubuntu 16, nginx 1.13.5) получается:
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie' --add-dynamic-module=../ngx_http_redis-0.3.8
В конце добавлен путь к динамическому модулю, который нужно скомпилировать (мы находимся в директории nginx ~/nginx-1.13.5), не забудьте его добавить:
--add-dynamic-module=../ngx_http_redis-0.3.8
Нажимаем Enter. Если вам повезло и на выходе нет ошибок, отлично.
Make
Дальше создаём модуль командой:
make modules
Если опять нет ошибок, то вы получите файл:
nginx-1.13.5/objs/ngx_http_redis_module.so
Подключаем его к NGINX, для этого в /etc/nginx/nginx.conf добавляем в самый верх строку с load_module, указываем полный путь до файла:
sudo nano /etc/nginx/nginx.conf
## Load our module:
load_module /home/vagrant/nginx-1.13.5/objs/ngx_http_redis_module.so;
Перезагружаем:
sudo nginx -s reload
Если нет сообщения об ошибке, значит модуль подключился! Можно переписать ngx_http_redis_module.so в более подходящее место и не забыть изменить путь к нему в nginx.conf.
Обновление NGINX
Модуль привязан к конкретной версии NGINX, если мы её обновим, то, скорее всего, он перестанет работать. Поэтому нужно пакет NGINX поставить на холд — заблокировать от обновления:
## sudo apt-mark hold <package>
sudo apt-mark hold nginx
## Remove HOLD
# sudo apt-mark unhold <package-name>
## Check HOLD
#apt-mark showhold
Ошибки и проблемы
Проблемы «configure»
1. Не проходит конфигурация билда, команда ./configure возвращает ошибку (после этого нельзя запустить make modules)
Ошибки такого вида:
./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib=<path> option.
В данном примере, если мы изменим конфигурацию (чтобы проходил ./configure) и поставим --without-http_gzip_module, скорее всего, на этапе подключения модуль не подойдёт к nginx (см. ниже)
В процессе могут вылетать разные требования к библиотекам, которые нужны для билда nginx (или не вылетать). Эти пакеты может понадобиться установить самостоятельно (а могут уже стоять):
1. "./configure: error: C compiler cc is not found"
sudo apt-get install build-essential
2. PCRE
sudo apt-get install libpcre3
sudo apt-get install libpcre3-dev
3. OpenSSL
sudo apt-get install libssl-dev
4. HTTP XSLT module requires the libxml2/libxslt
sudo apt-get install libxml2
sudo apt-get install libxml2-dev
sudo apt-get install libxslt-dev
5. «...the HTTP image filter module requires the GD library»
sudo apt-get install libgd-dev
6. GeoIP
sudo apt-get install libgeoip-dev
7. PAM authentication module
sudo apt-get install libpam-dev
Проблемы подключения
Когда удалось скомпилировать модуль, но не работает подключение в NGINX:
— Модуль module-name.so компилируется, но при перезагрузке nginx пишет, что не та версия — перепроверить и скачать соответствующую версию.
— «is not binary compatible» ошибка примерно такая:
nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_redis_module.so" is not binary compatible in /etc/nginx/nginx.conf:1
Это значит неправильно сконфигурирован билд модуля. Разбираемся с опциями ./configure: неправильно скопировали, не все зависимости установлены и так далее.