Установка OpenResty на Nginx в Ubuntu 16.04

OpenResty – это веб-сервер, который расширяет функции Nginx путём сборки дополнительных модулей и библиотек Lua. OpenResty отлично справляется с масштабированием веб-приложений и сервисов. Например, он содержит модуль, который позволяет писать код Lua и выполнять его непосредственно на Nginx, а это позволяет использовать высокопроизводительные приложения.

Данное руководство поможет установить OpenResty из исходного кода. Предварительно собранные пакеты для некоторых дистрибутивов могут быть устаревшими. Также здесь вы найдёте полезные примеры использования OpenResty.

Требования

  • Сервер Ubuntu 16.04.
  • Пользователь с доступом к sudo.
  • Настроенный брандмауэр.

Все дополнительные инструкции можно найти здесь.

Важно! Веб-сервер Nginx не должен быть установлен на сервере. Nginx включен в OpenResty, потому может возникнуть конфликт с предварительно установленной версией Nginx.

1: Загрузка исходного кода и зависимостей OpenResty

Для начала найдите последнюю версию исходного кода OpenResty на сайте проекта. Загрузите архив (версия может отличаться, в случае необходимости откорректируйте команду).

wget https://openresty.org/download/openresty-1.11.2.2.tar.gz

Загрузите gpg-ключ, чтобы проверить целостность файла.

wget https://openresty.org/download/openresty-1.11.2.2.tar.gz.asc

Затем нужно добавить открытый ключ автора, который можно найти на странице сайта. На момент написания статьи это ключ A0E98066. Убедитесь, что ключ не изменился (его можно найти на странице загрузки, с которой вы загрузили код).

gpg --keyserver pgpkeys.mit.edu --recv-key A0E98066

Вы увидите примерно такой вывод (условное имя текущего пользователя – 8host).

gpg: directory `/home/8host/.gnupg' created
gpg: new configuration file `/home/8host/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/8host/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/8host/.gnupg/secring.gpg' created
gpg: keyring `/home/8host/.gnupg/pubring.gpg' created
gpg: requesting key A0E98066 from hkp server pgpkeys.mit.edu
gpg: /home/8host/.gnupg/trustdb.gpg: trustdb created
gpg: key A0E98066: public key "Yichun Zhang (agentzh) <agentzh@gmail.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

Имя открытого ключа (в данном случае это Yichun Zhang) должно совпадать с именем, указанным на сайте OpenResty.

Теперь нужно убедиться, что файл подписи соответствует загруженному файлу .tar.gz.

gpg openresty-1.11.2.2.tar.gz.asc

Команда вернёт такой результат:

gpg: assuming signed data in `openresty-1.11.2.2.tar.gz'
gpg: Signature made Thu 17 Nov 2016 10:24:29 PM UTC using RSA key ID A0E98066
gpg: Good signature from "Yichun Zhang (agentzh) <agentzh@gmail.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 2545 1EB0 8846 0026 195B  D62C B550 E09E A0E9 8066

Появившееся предупреждение связано с тем, что вы не проверили, принадлежит ли этот ключ владельцу (т. е. вы не подписали открытый ключ с помощью своего закрытого ключа). Не существует простого способа убедиться, что этот открытый ключ принадлежит владельцу.

Однако фраза Good signature значит, что загруженный файл OpenResty действительно является файлом, который распространяют разработчики OpenResty. Такой файл можно установить.

Распакуйте загруженный файл и откройте полученный каталог.

tar -xvf openresty-1.11.2.2.tar.gz
cd openresty-1.11.2.2

Теперь нужно установить дополнительные инструменты для компиляции OpenResty.

Читайте также: Компиляция и установка пакетов из исходного кода с помощью make

sudo apt-get install build-essential

Также нужно установить такие пакеты:

  • readline: интерфейс командной строки OpenResty.
  • ncurses: ещё один компонент интерфейса командной строки OpenResty.
  • PCRE: регулярные выражения OpenResty.
  • OpenSSL: защита соединений по TLS (HTTPS).
  • Perl: язык программирования для OpenResty.

Чтобы установить зависимости, введите:

sudo apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl

Теперь всё готово к сборке и установке OpenResty.

2: Установка OpenResty

Соберите OpenResty с поддержкой регулярных выражений PCRE и IPv6. Флаг -j2 позволяет утилите make выполнять две задачи одновременно. Эта команда убедится, что все зависимости доступны и соберёт информацию для дальнейшей работы. Также она соберёт некоторые зависимости (например, LuaJIT).

./configure -j2 --with-pcre-jit --with-ipv6

Теперь вы можете собрать OpenResty. Добавьте в команду флаг -j2. Эта команда скомпилирует OpenResty:

make -j2

Установите OpenResty. Благодаря команде sudo все файлы будут скопированы в правильное место в системе, и OpenResty быстро найдёт их при запуске

sudo make install

Разблокируйте HTTP в брандмауэре:

sudo ufw allow http

Также можно разблокировать HTTPS (это опционально).

sudo ufw allow https

Чтобы проверить правила брандмауэра, запросите его состояние:

sudo ufw status

В списке сервисов вы увидите HTTP и порт 80 (также HTTPS и порт 443, если вы его разблокировали).

Status: active
To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80                         ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80 (v6)                    ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Убедитесь, что установка прошла успешно. Запустите OpenResty:

sudo /usr/local/openresty/bin/openresty

Если команда выполнена успешно, она будет немедленно завершена без вывода. В таком случае вы можете открыть в браузере:

http://your_server_ip

Вы увидите страницу:

Welcome to OpenResty!

Если это так, значит, установка прошла успешно.

Остановите сервер OpenResty:

sudo /usr/local/openresty/bin/openresty -s quit

Сервер OpenResty установлен. Теперь нужно настроить автозапуск сервиса OpenResty (иначе его придётся запускать вручную после каждой перезагрузки).

3: Настройка сервиса OpenResty

Теперь нужно настроить OpenResty как сервис, чтобы он автоматически запускался вместе с сервером. Для этого используется система инициализации systemd.

Читайте также: Основы Systemd: управление сервисами и журналирование

Для начала создайте файл systemd в текстовом редакторе.

sudo nano /etc/systemd/system/openresty.service

В качестве шаблона для файла OpenResty в руководстве используется файл systemd веб-сервера Nginx по умолчанию. Он содержит следующие параметры. Его содержимое нужно скопировать и поместить в только что созданный файл.

# Stop dance for OpenResty
# A modification of the Nginx systemd script
# =======================
#
# ExecStop sends SIGSTOP (graceful stop) to the Nginx process.
# If, after 5s (--retry QUIT/5) OpenResty is still running, systemd takes control
# and sends SIGTERM (fast shutdown) to the main process.
# After another 5s (TimeoutStopSec=5), and if OpenResty is alive, systemd sends
# SIGKILL to all the remaining processes in the process group (KillMode=mixed).
#
# Nginx signals reference doc:
# http://nginx.org/en/docs/control.html
#
[Unit] Description=A dynamic web platform based on Nginx and LuaJIT.
After=network.target
[Service] Type=forking
PIDFile=/run/openresty.pid
ExecStartPre=/usr/local/openresty/bin/openresty -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/local/openresty/bin/openresty -g 'daemon on; master_process on;'
ExecReload=/usr/local/openresty/bin/openresty -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/openresty.pid
TimeoutStopSec=5
KillMode=mixed
[Install] WantedBy=multi-user.target

В разделе [Unit] директива After=network.target запускает OpenResty после запуска сети, после чего OpenResty может начинать прослушивание портов.

В разделе [Service]:

  • Директива Type=forking сообщает systemd, что вызываемый в ExecStart процесс запустит сервис в фоновом режиме, после чего остановится.
  • PIDFile=/run/openresty.pid определяет, где искать PID-файл, который OpenResty создаёт при запуске. Так systemd определяет, запущен ли сервер OpenResty.
  • ExecStartPre=/usr/local/openresty/bin/openresty -t -q -g ‘daemon on; master_process on;’ вызывает сценарий OpenResty, не запуская его. Флаг -t тестирует конфигурационный файл; флаг -q подавляет вывод без ошибок; -g устанавливает глобальные директивы «daemon on; master_process on», которые запускают демон OpenResty в фоновом режиме. Сценарий выполняется как ExecStartPre, потому systemd не будет запускать OpenResty, если конфигурационный файл недействителен.
  • ExecStart=/usr/local/openresty/bin/openresty -g ‘daemon on; master_process on;’ запускает OpenReesty. Данный параметр содержит те же настройки, что и ExecStartPre, кроме флага –t.
  • ExecReload=/usr/local/openresty/bin/openresty -g ‘daemon on; master_process on;’ -s reload запускает команду при запуске команды systemctl reload openresty. Флаг –s перезагружает конфигурационный файл OpenResty.
  • ExecStop=-/sbin/start-stop-daemon –quiet –stop –retry QUIT/5 –pidfile /run/openresty.pid запускает команду, когда сервис OpenResty остановлен. Данный параметр отправляет сигнал SIGSTOP процессу, указанному в PID-файле. Если в течение 5 секунд сервис не останавливается, systemd использует следующие две опции.
  • TimeoutStopSec=5 определяет, что процесс должен остановиться в течение 5 секунд. Если он не остановится, systemd попытается принудительно остановить OpenResty.
  • KillMode=mixed определяет, как именно systemd будет останавливать OpenResty, если процесс не прервётся в течение 5 секунд.

Параметр WantedBy=multi-user.target в разделе [Install] указывает, когда нужно запустить сервис OpenResty, если его нужно запускать во время загрузки сервера. Значение multi-user.target определяет, что сервис будет запущен только при запуске многопользовательской системы, то есть вы можете запустить OpenResty как другого пользователя.

Далее нужно откорректировать конфигурационный файл Nginx для OpenResty и включить сервис.

Сначала откройте конфигурационный файл:

sudo nano /usr/local/openresty/nginx/conf/nginx.conf

По умолчанию он выглядит так:

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
worker_connections  1024;
}
. . .

Замените все строки до строки events { следующими параметрами:

user www-data;
worker_processes  auto;
pid /run/openresty.pid;
events {
worker_connections  1024;
}
. . .

Теперь сервис будет запускаться как пользователь www-data, и systemd сможет определить, запущен ли сервис OpenResty, с помощью строки pid, которую OpenResty будет создавать при запуске.

Сохраните и закройте файл.

Создайте каталог для лог-файлов.

sudo mkdir /var/log/openresty

Перезапустите systemd, чтобы обновить настройки.

sudo systemctl daemon-reload

Запустите OpenResty с помощью systemd.

sudo systemctl start openresty

Откройте в браузере:

http://your_server_ip

Вы должны увидеть ту же страницу, что и раньше. Разница только в том, что в этот раз сервер запущен не вручную, а с помощью systemd.

Теперь включите сервис OpenResty:

sudo systemctl enable openresty

4: Настройка OpenResty

В качестве шаблона для настройки OpenResty можно использовать конфигурационный файл Nginx по умолчанию.

Откройте конфигурации OpenResty:

sudo nano /usr/local/openresty/nginx/conf/nginx.conf

Отредактируйте блок http и переместите из него блок server в другой файл. Для начала найдите строку http { и удалите всё после неё до строки }.

user www-data;
worker_processes  auto;
pid /run/openresty.pid;
events {
worker_connections  1024;
}
http {
include       mime.types;
default_type  application/octet-stream;
. . .
}

Скопируйте и вставьте следующий блок http:

user www-data;
worker_processes  auto;
pid /run/openresty.pid;
events {
worker_connections  1024;
}
http {
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
tcp_nopush      on;
tcp_nodelay     on;
keepalive_timeout  65;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/openresty/access.log;
error_log /var/log/openresty/error.log;
gzip  on;
gzip_disable "msie6";
include ../sites/*;
}

Сохраните и закройте файл.

Рассмотрим подробнее новые параметры:

  • Раскомментированный параметр tcp_nopush on; будет отправлять только полные пакеты. Эта опция хорошо работает в связке с sendfile, что позволит OpenResty оптимизировать отправку статических файлов клиенту.
  • Параметр tcp_nodelay on; попытается отправить пакеты как можно скорее, что, на первый взгляд, противоречит вышеуказанной опции. Но этот параметр используется только с опцией keepalive для запросов HTTP (т. е. для соединений с веб-сервером с помощью веб-браузера). Это уменьшает расход ресурсов при инициировании HTTP-соединения каждый раз, когда выполняется запрос.
  • Строки ssl_protocols и ssl_prefer_server_ciphers настраивают SSL. Предыдущие параметры уязвимы к некоторым атакам, потому их лучше удалить.
  • Строки access_log и error_log настраивают логи веб-сервера. Логи будут храниться в /var/log/openresty.
  • Параметры gzip on и gzip_disable “msie6” настраивают GZIP, который будет сжимать веб-страницы и, таким образом, уменьшать количество данных для передачи. Последняя опция нужна, так как Internet Explorer 6 и некоторые другие старые браузеры не всегда поддерживают GZIP.
  • include ../sites/*; указывает, что дополнительные конфигурационные файлы OpenResty хранятся в /usr/local/openresty/nginx/sites.
  • Все блоки server были удалены. В дальнейшем их нужно перенести в другой файл.

Создайте каталог sites, который был указан в строке include.

sudo mkdir /usr/local/openresty/nginx/sites

Создайте файл default:

sudo nano /usr/local/openresty/nginx/sites/default.conf

В этот файл добавьте следующие строки (это блоки server из исходного файла nginx.conf с комментариями).

server {
# Listen on port 80.
listen 80 default_server;
listen [::]:80 default_server;
# The document root.
root /usr/local/openresty/nginx/html/default;
# Add index.php if you are using PHP.
index index.html index.htm;
# The server name, which isn't relevant in this case, because we only have one.
server_name _;
# When we try to access this site...
location / {
# ... first attempt to serve request as file, then as a directory,
# then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# Redirect server error pages to the static page /50x.html.
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
}

Сохраните и закройте файл.

Создайте новый каталог для этого сайта:

sudo mkdir /usr/local/openresty/nginx/html/default

Переместите файл index.html из его первоначального расположения в новый каталог.

sudo mv /usr/local/openresty/nginx/html/index.html /usr/local/openresty/nginx/html/default

Перезапустите OpenResty, чтобы обновить настройки.

sudo systemctl restart openresty

Попробуйте снова открыть в браузере:

http://your_server_ip

Вы увидите ту же страницу, что и раньше.

Сервер OpenResty полностью готов к работе.

5: Использование OpenResty и модуля Lua

Теперь попробуйте поработать с комбинациями модулей, добавленных сервером OpenResty, которые предназначены для размещения сценариев Lua. Отредактируйте /usr/local/openresty/nginx/sites/default.conf.

sudo nano /usr/local/openresty/nginx/sites/default.conf

Найдите опцию content_by_lua_block. Скопируйте следующий блок location и вставьте его в блок server под двумя ранее добавленными блоками location.

server {
. . .
location /example {
default_type 'text/plain';
content_by_lua_block {
ngx.say('Hello, World!')
}
}
}

Сохраните и закройте файл. Перезапустите сервис:

sudo systemctl reload openresty

Если теперь открыть ссылку:

http://your_server_ip/example

На странице вы увидите:

Hello, World!

Директива content_by_lua_block выполняет любое своё значение как код Lua. В данном случае используется функция Lua ngx.say, которая отображает сообщение «Hello, World!».

Для примера попробуйте изменить содержимое блока location /example.

server {
. . .
location /example {
default_type 'text/plain';
content_by_lua_file /usr/local/openresty/nginx/html/default/index.lua;
}
}

Директива content_by_lua_file загружает контент Lua из внешнего файла. Теперь создайте такой файл, /usr/local/openresty/nginx/html/default/index.lua.

sudo nano /usr/local/openresty/nginx/html/default/index.lua

Добавьте в него:

local name = ngx.var.arg_name or "Anonymous"
ngx.say("Hello, ", name, "!")

Сохраните и закройте файл.

Это простой пример Lua, который читает параметр запроса name в URL-адресе и настраивает сообщение-приветствие. Если параметр name не передан, вместо него используется «Anonymous».

Перезапустите сервис:

sudo systemctl reload openresty

Теперь попробуйте открыть в браузере ссылку:

http://your_server_ip/example?name=8host

На экране появится:

Hello, 8host!

Важно! Не размещайте файл Lua в каталоге, доступ к которому есть в Интернете. При этом посторонний пользователь может обратиться к файлу и запустить код приложения. Файлы Lua нужно хранить вне каталога document root. Например, можно перенести document root в /usr/local/openresty/nginx/html/default/public, а файлы хранить в каталоге уровнем выше.

Заключение

Теперь вы умеете устанавливать OpenResty и добавлять сценарии Lua в рабочий процесс Nginx.

Вы можете создать более сложные сценарии Lua, ограничить доступ к ним или переписать с их помощью некоторые запросы.

Документацию Lua-модулей для Nginx можно найти здесь.

Больше информации о OpenResty вы найдёте на сайте проекта.

Читайте также: Настройка виртуальных хостов Nginx в Ubuntu 16.04

Tags: , , ,

1 комментарий

Добавить комментарий